diff --git a/.DS_Store b/.DS_Store
index 6932e4b1..feb9a3ee 100644
Binary files a/.DS_Store and b/.DS_Store differ
diff --git a/.idea/misc.xml b/.idea/misc.xml
index 9027e22a..cfe73808 100644
--- a/.idea/misc.xml
+++ b/.idea/misc.xml
@@ -14,4 +14,7 @@
+
+
+
\ No newline at end of file
diff --git a/accounts/__pycache__/flows.cpython-312.pyc b/accounts/__pycache__/flows.cpython-312.pyc
new file mode 100644
index 00000000..b12ee7ba
Binary files /dev/null and b/accounts/__pycache__/flows.cpython-312.pyc differ
diff --git a/accounts/__pycache__/forms.cpython-312.pyc b/accounts/__pycache__/forms.cpython-312.pyc
index 5dca14a0..6708f721 100644
Binary files a/accounts/__pycache__/forms.cpython-312.pyc and b/accounts/__pycache__/forms.cpython-312.pyc differ
diff --git a/accounts/__pycache__/views.cpython-312.pyc b/accounts/__pycache__/views.cpython-312.pyc
index 46b14088..44e99a6d 100644
Binary files a/accounts/__pycache__/views.cpython-312.pyc and b/accounts/__pycache__/views.cpython-312.pyc differ
diff --git a/accounts/flows.py b/accounts/flows.py
new file mode 100644
index 00000000..989b74ad
--- /dev/null
+++ b/accounts/flows.py
@@ -0,0 +1,800 @@
+# """
+# Viewflow workflows for accounts app.
+# Provides user management, authentication, and security workflows.
+# """
+#
+# from viewflow import this, jsonstore
+# from viewflow.workflow import lock, flow, act
+# # from viewflow.base import flow_func
+# # from viewflow.workflow.base import Flow
+# from viewflow.workflow import celery
+# # from viewflow.decorators import flow_view
+# from viewflow.jsonstore import CharField
+# from viewflow.forms import ModelForm
+# from viewflow.fields import ModelField
+# from viewflow.workflow.flow.views import CreateProcessView, UpdateProcessView
+# from viewflow.workflow.models import Process, Task
+# from django.urls import reverse_lazy
+# from django.utils import timezone
+# from django.db import transaction
+# from django.core.mail import send_mail
+#
+# from .models import User, TwoFactorDevice, SocialAccount, UserSession, PasswordHistory
+# from .views import *
+#
+#
+# class UserOnboardingProcess(Process):
+# """
+# Viewflow process model for user onboarding
+# """
+# user = ModelField(User, help_text='Associated user')
+#
+# # Process status tracking
+# registration_submitted = models.BooleanField(default=False)
+# account_created = models.BooleanField(default=False)
+# email_verified = models.BooleanField(default=False)
+# profile_completed = models.BooleanField(default=False)
+# permissions_assigned = models.BooleanField(default=False)
+# security_setup = models.BooleanField(default=False)
+# training_completed = models.BooleanField(default=False)
+# onboarding_completed = models.BooleanField(default=False)
+#
+# class Meta:
+# verbose_name = 'User Onboarding Process'
+# verbose_name_plural = 'User Onboarding Processes'
+#
+#
+# class UserOnboardingFlow(flow.Flow):
+# """
+# User Onboarding Workflow
+#
+# This flow manages complete user onboarding from registration
+# through account setup, security configuration, and training.
+# """
+#
+# process_class = UserOnboardingProcess
+#
+# # Flow definition
+# start = (
+# flow_func(this.start_user_onboarding)
+# .Next(this.register_user)
+# )
+#
+# register_user = (
+# flow_view(UserRegistrationView)
+# .Permission('accounts.can_register_users')
+# .Next(this.create_account)
+# )
+#
+# create_account = (
+# flow_func(this.setup_user_account)
+# .Next(this.verify_email)
+# )
+#
+# verify_email = (
+# flow_view(AccountActivationView)
+# .Permission('accounts.can_activate_accounts')
+# .Next(this.complete_profile)
+# )
+#
+# complete_profile = (
+# flow_func(this.setup_user_profile)
+# .Next(this.assign_permissions)
+# )
+#
+# assign_permissions = (
+# flow_view(PermissionManagementView)
+# .Permission('accounts.can_manage_permissions')
+# .Next(this.setup_security)
+# )
+#
+# setup_security = (
+# flow_view(TwoFactorSetupView)
+# .Permission('accounts.can_setup_security')
+# .Next(this.complete_training)
+# )
+#
+# complete_training = (
+# flow_func(this.assign_training_modules)
+# .Next(this.finalize_onboarding)
+# )
+#
+# finalize_onboarding = (
+# flow_func(this.complete_user_onboarding)
+# .Next(this.end)
+# )
+#
+# end = flow_func(this.end_user_onboarding)
+#
+# # Flow functions
+# def start_user_onboarding(self, activation):
+# """Initialize the user onboarding process"""
+# process = activation.process
+# user = process.user
+#
+# # Send onboarding notification
+# self.notify_onboarding_start(user)
+#
+# # Create onboarding checklist
+# self.create_onboarding_checklist(user)
+#
+# def setup_user_account(self, activation):
+# """Setup user account with initial configuration"""
+# process = activation.process
+# user = process.user
+#
+# # Configure account settings
+# self.configure_account_settings(user)
+#
+# # Mark account created
+# process.account_created = True
+# process.save()
+#
+# # Send welcome email
+# self.send_welcome_email(user)
+#
+# def setup_user_profile(self, activation):
+# """Setup user profile information"""
+# process = activation.process
+# user = process.user
+#
+# # Complete profile setup
+# self.complete_profile_setup(user)
+#
+# # Mark profile completed
+# process.profile_completed = True
+# process.save()
+#
+# # Generate employee ID if needed
+# self.generate_employee_id(user)
+#
+# def assign_training_modules(self, activation):
+# """Assign required training modules"""
+# process = activation.process
+# user = process.user
+#
+# # Assign role-based training
+# self.assign_role_training(user)
+#
+# # Mark training assigned
+# process.training_completed = True
+# process.save()
+#
+# # Send training notifications
+# self.notify_training_assignment(user)
+#
+# def complete_user_onboarding(self, activation):
+# """Complete the user onboarding process"""
+# process = activation.process
+# user = process.user
+#
+# # Activate user account
+# user.is_active = True
+# user.save()
+#
+# # Mark onboarding completed
+# process.onboarding_completed = True
+# process.save()
+#
+# # Send completion notifications
+# self.notify_onboarding_completion(user)
+#
+# # Create initial session
+# self.create_initial_session(user)
+#
+# def end_user_onboarding(self, activation):
+# """End the user onboarding workflow"""
+# process = activation.process
+#
+# # Generate onboarding summary
+# self.generate_onboarding_summary(process.user)
+#
+# # Helper methods
+# def notify_onboarding_start(self, user):
+# """Notify onboarding start"""
+# # Notify HR and IT teams
+# hr_staff = User.objects.filter(groups__name='HR Staff')
+# for staff in hr_staff:
+# send_mail(
+# subject=f'New User Onboarding: {user.get_full_name()}',
+# message=f'User onboarding process started for {user.username}.',
+# from_email='accounts@hospital.com',
+# recipient_list=[staff.email],
+# fail_silently=True
+# )
+#
+# def create_onboarding_checklist(self, user):
+# """Create onboarding checklist"""
+# # This would create a checklist for the user
+# pass
+#
+# def configure_account_settings(self, user):
+# """Configure initial account settings"""
+# # This would set up default account settings
+# pass
+#
+# def send_welcome_email(self, user):
+# """Send welcome email to new user"""
+# if user.email:
+# send_mail(
+# subject='Welcome to Hospital Management System',
+# message=f'Welcome {user.get_full_name()}! Your account has been created.',
+# from_email='accounts@hospital.com',
+# recipient_list=[user.email],
+# fail_silently=True
+# )
+#
+# def complete_profile_setup(self, user):
+# """Complete user profile setup"""
+# # This would complete profile configuration
+# pass
+#
+# def generate_employee_id(self, user):
+# """Generate employee ID for user"""
+# if not user.employee_id:
+# # Generate unique employee ID
+# user.employee_id = f"EMP{user.id:06d}"
+# user.save()
+#
+# def assign_role_training(self, user):
+# """Assign role-based training modules"""
+# # This would assign training based on user role
+# pass
+#
+# def notify_training_assignment(self, user):
+# """Notify training assignment"""
+# if user.email:
+# send_mail(
+# subject='Training Modules Assigned',
+# message='Training modules have been assigned to your account.',
+# from_email='training@hospital.com',
+# recipient_list=[user.email],
+# fail_silently=True
+# )
+#
+# def notify_onboarding_completion(self, user):
+# """Notify onboarding completion"""
+# if user.email:
+# send_mail(
+# subject='Onboarding Complete',
+# message='Your onboarding process has been completed successfully.',
+# from_email='accounts@hospital.com',
+# recipient_list=[user.email],
+# fail_silently=True
+# )
+#
+# def create_initial_session(self, user):
+# """Create initial user session"""
+# # This would create the first user session
+# pass
+#
+# def generate_onboarding_summary(self, user):
+# """Generate onboarding summary"""
+# # This would generate onboarding completion report
+# pass
+#
+#
+# class SecurityManagementProcess(Process):
+# """
+# Viewflow process model for security management
+# """
+# user = ModelField(User, help_text='Associated user')
+#
+# # Process status tracking
+# security_assessment = models.BooleanField(default=False)
+# two_factor_setup = models.BooleanField(default=False)
+# password_policy_applied = models.BooleanField(default=False)
+# session_configured = models.BooleanField(default=False)
+# audit_completed = models.BooleanField(default=False)
+# compliance_verified = models.BooleanField(default=False)
+# security_completed = models.BooleanField(default=False)
+#
+# class Meta:
+# verbose_name = 'Security Management Process'
+# verbose_name_plural = 'Security Management Processes'
+#
+#
+# class SecurityManagementFlow(flow.Flow):
+# """
+# Security Management Workflow
+#
+# This flow manages user security setup including two-factor
+# authentication, password policies, and compliance verification.
+# """
+#
+# process_class = SecurityManagementProcess
+#
+# # Flow definition
+# start = (
+# flow_func(this.start_security_management)
+# .Next(this.assess_security)
+# )
+#
+# assess_security = (
+# flow_view(SecurityAuditView)
+# .Permission('accounts.can_audit_security')
+# .Next(this.setup_two_factor)
+# )
+#
+# setup_two_factor = (
+# flow_view(TwoFactorSetupView)
+# .Permission('accounts.can_setup_two_factor')
+# .Next(this.apply_password_policy)
+# )
+#
+# apply_password_policy = (
+# flow_func(this.enforce_password_policy)
+# .Next(this.configure_session)
+# )
+#
+# configure_session = (
+# flow_view(SessionManagementView)
+# .Permission('accounts.can_manage_sessions')
+# .Next(this.complete_audit)
+# )
+#
+# complete_audit = (
+# flow_func(this.perform_security_audit)
+# .Next(this.verify_compliance)
+# )
+#
+# verify_compliance = (
+# flow_view(ComplianceCheckView)
+# .Permission('accounts.can_verify_compliance')
+# .Next(this.finalize_security)
+# )
+#
+# finalize_security = (
+# flow_func(this.complete_security_management)
+# .Next(this.end)
+# )
+#
+# end = flow_func(this.end_security_management)
+#
+# # Flow functions
+# def start_security_management(self, activation):
+# """Initialize the security management process"""
+# process = activation.process
+# user = process.user
+#
+# # Send security setup notification
+# self.notify_security_setup(user)
+#
+# # Create security checklist
+# self.create_security_checklist(user)
+#
+# def enforce_password_policy(self, activation):
+# """Enforce password policy requirements"""
+# process = activation.process
+# user = process.user
+#
+# # Apply password policy
+# self.apply_password_requirements(user)
+#
+# # Mark password policy applied
+# process.password_policy_applied = True
+# process.save()
+#
+# # Create password history entry
+# self.create_password_history(user)
+#
+# def perform_security_audit(self, activation):
+# """Perform comprehensive security audit"""
+# process = activation.process
+# user = process.user
+#
+# # Conduct security audit
+# audit_results = self.conduct_security_audit(user)
+#
+# # Mark audit completed
+# process.audit_completed = True
+# process.save()
+#
+# # Store audit results
+# self.store_audit_results(user, audit_results)
+#
+# def complete_security_management(self, activation):
+# """Complete the security management process"""
+# process = activation.process
+# user = process.user
+#
+# # Mark security completed
+# process.security_completed = True
+# process.save()
+#
+# # Send completion notifications
+# self.notify_security_completion(user)
+#
+# # Schedule security review
+# self.schedule_security_review(user)
+#
+# def end_security_management(self, activation):
+# """End the security management workflow"""
+# process = activation.process
+#
+# # Generate security summary
+# self.generate_security_summary(process.user)
+#
+# # Helper methods
+# def notify_security_setup(self, user):
+# """Notify security setup start"""
+# security_team = User.objects.filter(groups__name='Security Team')
+# for staff in security_team:
+# send_mail(
+# subject=f'Security Setup: {user.get_full_name()}',
+# message=f'Security setup process started for {user.username}.',
+# from_email='security@hospital.com',
+# recipient_list=[staff.email],
+# fail_silently=True
+# )
+#
+# def create_security_checklist(self, user):
+# """Create security setup checklist"""
+# # This would create security checklist
+# pass
+#
+# def apply_password_requirements(self, user):
+# """Apply password policy requirements"""
+# # This would enforce password policy
+# pass
+#
+# def create_password_history(self, user):
+# """Create password history entry"""
+# # This would create password history record
+# pass
+#
+# def conduct_security_audit(self, user):
+# """Conduct comprehensive security audit"""
+# # This would perform security audit
+# return {'status': 'passed', 'issues': []}
+#
+# def store_audit_results(self, user, results):
+# """Store security audit results"""
+# # This would store audit results
+# pass
+#
+# def notify_security_completion(self, user):
+# """Notify security setup completion"""
+# if user.email:
+# send_mail(
+# subject='Security Setup Complete',
+# message='Your security setup has been completed successfully.',
+# from_email='security@hospital.com',
+# recipient_list=[user.email],
+# fail_silently=True
+# )
+#
+# def schedule_security_review(self, user):
+# """Schedule periodic security review"""
+# # Schedule security review task
+# schedule_security_review.apply_async(
+# args=[user.id],
+# countdown=86400 * 90 # 90 days
+# )
+#
+# def generate_security_summary(self, user):
+# """Generate security setup summary"""
+# # This would generate security summary
+# pass
+#
+#
+# class AccountDeactivationProcess(Process):
+# """
+# Viewflow process model for account deactivation
+# """
+# user = ModelField(User, help_text='Associated user')
+#
+# # Process status tracking
+# deactivation_requested = models.BooleanField(default=False)
+# data_backup_completed = models.BooleanField(default=False)
+# access_revoked = models.BooleanField(default=False)
+# sessions_terminated = models.BooleanField(default=False)
+# notifications_sent = models.BooleanField(default=False)
+# account_archived = models.BooleanField(default=False)
+# deactivation_completed = models.BooleanField(default=False)
+#
+# class Meta:
+# verbose_name = 'Account Deactivation Process'
+# verbose_name_plural = 'Account Deactivation Processes'
+#
+#
+# class AccountDeactivationFlow(flow.Flow):
+# """
+# Account Deactivation Workflow
+#
+# This flow manages secure account deactivation including
+# data backup, access revocation, and proper archival.
+# """
+#
+# process_class = AccountDeactivationProcess
+#
+# # Flow definition
+# start = (
+# flow_func(this.start_account_deactivation)
+# .Next(this.request_deactivation)
+# )
+#
+# request_deactivation = (
+# flow_view(AccountDeactivationView)
+# .Permission('accounts.can_deactivate_accounts')
+# .Next(this.backup_data)
+# )
+#
+# backup_data = (
+# flow_func(this.perform_data_backup)
+# .Next(this.revoke_access)
+# )
+#
+# revoke_access = (
+# flow_func(this.revoke_user_access)
+# .Next(this.terminate_sessions)
+# )
+#
+# terminate_sessions = (
+# flow_func(this.end_user_sessions)
+# .Next(this.send_notifications)
+# )
+#
+# send_notifications = (
+# flow_func(this.notify_deactivation)
+# .Next(this.archive_account)
+# )
+#
+# archive_account = (
+# flow_func(this.archive_user_account)
+# .Next(this.complete_deactivation)
+# )
+#
+# complete_deactivation = (
+# flow_func(this.finalize_account_deactivation)
+# .Next(this.end)
+# )
+#
+# end = flow_func(this.end_account_deactivation)
+#
+# # Flow functions
+# def start_account_deactivation(self, activation):
+# """Initialize the account deactivation process"""
+# process = activation.process
+# user = process.user
+#
+# # Send deactivation notification
+# self.notify_deactivation_start(user)
+#
+# # Create deactivation checklist
+# self.create_deactivation_checklist(user)
+#
+# def perform_data_backup(self, activation):
+# """Perform user data backup"""
+# process = activation.process
+# user = process.user
+#
+# # Backup user data
+# self.backup_user_data(user)
+#
+# # Mark backup completed
+# process.data_backup_completed = True
+# process.save()
+#
+# # Verify backup integrity
+# self.verify_backup_integrity(user)
+#
+# def revoke_user_access(self, activation):
+# """Revoke user access and permissions"""
+# process = activation.process
+# user = process.user
+#
+# # Revoke all permissions
+# self.revoke_permissions(user)
+#
+# # Mark access revoked
+# process.access_revoked = True
+# process.save()
+#
+# # Log access revocation
+# self.log_access_revocation(user)
+#
+# def end_user_sessions(self, activation):
+# """Terminate all user sessions"""
+# process = activation.process
+# user = process.user
+#
+# # End all active sessions
+# self.terminate_all_sessions(user)
+#
+# # Mark sessions terminated
+# process.sessions_terminated = True
+# process.save()
+#
+# # Log session termination
+# self.log_session_termination(user)
+#
+# def notify_deactivation(self, activation):
+# """Send deactivation notifications"""
+# process = activation.process
+# user = process.user
+#
+# # Send notifications to relevant parties
+# self.send_deactivation_notifications(user)
+#
+# # Mark notifications sent
+# process.notifications_sent = True
+# process.save()
+#
+# def archive_user_account(self, activation):
+# """Archive user account"""
+# process = activation.process
+# user = process.user
+#
+# # Archive account data
+# self.archive_account_data(user)
+#
+# # Mark account archived
+# process.account_archived = True
+# process.save()
+#
+# # Update account status
+# self.update_account_status(user)
+#
+# def finalize_account_deactivation(self, activation):
+# """Finalize the account deactivation process"""
+# process = activation.process
+# user = process.user
+#
+# # Deactivate user account
+# user.is_active = False
+# user.save()
+#
+# # Mark deactivation completed
+# process.deactivation_completed = True
+# process.save()
+#
+# # Send final notifications
+# self.notify_deactivation_completion(user)
+#
+# def end_account_deactivation(self, activation):
+# """End the account deactivation workflow"""
+# process = activation.process
+#
+# # Generate deactivation summary
+# self.generate_deactivation_summary(process.user)
+#
+# # Helper methods
+# def notify_deactivation_start(self, user):
+# """Notify deactivation start"""
+# hr_staff = User.objects.filter(groups__name='HR Staff')
+# for staff in hr_staff:
+# send_mail(
+# subject=f'Account Deactivation: {user.get_full_name()}',
+# message=f'Account deactivation process started for {user.username}.',
+# from_email='accounts@hospital.com',
+# recipient_list=[staff.email],
+# fail_silently=True
+# )
+#
+# def create_deactivation_checklist(self, user):
+# """Create deactivation checklist"""
+# # This would create deactivation checklist
+# pass
+#
+# def backup_user_data(self, user):
+# """Backup user data"""
+# # This would backup all user data
+# pass
+#
+# def verify_backup_integrity(self, user):
+# """Verify backup integrity"""
+# # This would verify backup completeness
+# pass
+#
+# def revoke_permissions(self, user):
+# """Revoke all user permissions"""
+# # This would revoke all permissions
+# user.groups.clear()
+# user.user_permissions.clear()
+#
+# def log_access_revocation(self, user):
+# """Log access revocation"""
+# # This would log the access revocation
+# pass
+#
+# def terminate_all_sessions(self, user):
+# """Terminate all user sessions"""
+# user.user_sessions.filter(is_active=True).update(
+# is_active=False,
+# ended_at=timezone.now()
+# )
+#
+# def log_session_termination(self, user):
+# """Log session termination"""
+# # This would log session termination
+# pass
+#
+# def send_deactivation_notifications(self, user):
+# """Send deactivation notifications"""
+# # This would send notifications to relevant parties
+# pass
+#
+# def archive_account_data(self, user):
+# """Archive account data"""
+# # This would archive account data
+# pass
+#
+# def update_account_status(self, user):
+# """Update account status"""
+# # This would update account status
+# pass
+#
+# def notify_deactivation_completion(self, user):
+# """Notify deactivation completion"""
+# # This would notify completion
+# pass
+#
+# def generate_deactivation_summary(self, user):
+# """Generate deactivation summary"""
+# # This would generate deactivation summary
+# pass
+#
+#
+# # Celery tasks for background processing
+# @celery.job
+# def schedule_security_review(user_id):
+# """Background task to schedule security review"""
+# try:
+# user = User.objects.get(id=user_id)
+#
+# # Create security review task
+# # This would create a security review task
+#
+# return True
+# except Exception:
+# return False
+#
+#
+# @celery.job
+# def cleanup_expired_sessions():
+# """Background task to cleanup expired sessions"""
+# try:
+# # Cleanup expired sessions
+# expired_sessions = UserSession.objects.filter(
+# expires_at__lt=timezone.now(),
+# is_active=True
+# )
+#
+# for session in expired_sessions:
+# session.end_session()
+#
+# return True
+# except Exception:
+# return False
+#
+#
+# @celery.job
+# def audit_user_accounts():
+# """Background task to audit user accounts"""
+# try:
+# # This would perform periodic user account audits
+# return True
+# except Exception:
+# return False
+#
+#
+# @celery.job
+# def enforce_password_expiry():
+# """Background task to enforce password expiry"""
+# try:
+# # This would enforce password expiry policies
+# return True
+# except Exception:
+# return False
+#
+#
+# @celery.job
+# def generate_security_reports():
+# """Background task to generate security reports"""
+# try:
+# # This would generate periodic security reports
+# return True
+# except Exception:
+# return False
+#
diff --git a/accounts/forms.py b/accounts/forms.py
index e0fcebca..229d940f 100644
--- a/accounts/forms.py
+++ b/accounts/forms.py
@@ -223,3 +223,721 @@ class PasswordChangeForm(forms.Form):
self.user.save()
return self.user
+
+# from django import forms
+# from django.contrib.auth.forms import UserCreationForm, PasswordChangeForm
+# from django.contrib.auth.models import User, Group
+# from django.core.exceptions import ValidationError
+# from django.utils import timezone
+# from django.contrib.auth.password_validation import validate_password
+# from crispy_forms.helper import FormHelper
+# from crispy_forms.layout import Layout, Fieldset, Submit, Row, Column, HTML, Div
+# from crispy_forms.bootstrap import FormActions
+#
+# from .models import User, TwoFactorDevice, SocialAccount, UserSession, PasswordHistory
+#
+#
+# class UserRegistrationForm(UserCreationForm):
+# """
+# Form for user registration in onboarding workflow
+# """
+# first_name = forms.CharField(
+# max_length=150,
+# required=True,
+# widget=forms.TextInput(attrs={'class': 'form-control'})
+# )
+# last_name = forms.CharField(
+# max_length=150,
+# required=True,
+# widget=forms.TextInput(attrs={'class': 'form-control'})
+# )
+# email = forms.EmailField(
+# required=True,
+# widget=forms.EmailInput(attrs={'class': 'form-control'})
+# )
+# employee_id = forms.CharField(
+# max_length=50,
+# required=False,
+# widget=forms.TextInput(attrs={'class': 'form-control'})
+# )
+# department = forms.ModelChoiceField(
+# queryset=None, # Will be set in __init__
+# required=True,
+# widget=forms.Select(attrs={'class': 'form-control'})
+# )
+# job_title = forms.CharField(
+# max_length=200,
+# required=True,
+# widget=forms.TextInput(attrs={'class': 'form-control'})
+# )
+# phone_number = forms.CharField(
+# max_length=20,
+# required=False,
+# widget=forms.TextInput(attrs={'class': 'form-control'})
+# )
+# start_date = forms.DateField(
+# required=True,
+# widget=forms.DateInput(attrs={'class': 'form-control', 'type': 'date'})
+# )
+# manager = forms.ModelChoiceField(
+# queryset=None, # Will be set in __init__
+# required=False,
+# widget=forms.Select(attrs={'class': 'form-control'})
+# )
+#
+# class Meta:
+# model = User
+# fields = [
+# 'username', 'first_name', 'last_name', 'email', 'employee_id',
+# 'department', 'job_title', 'phone_number', 'start_date', 'manager',
+# 'password1', 'password2'
+# ]
+#
+# def __init__(self, *args, **kwargs):
+# tenant = kwargs.pop('tenant', None)
+# super().__init__(*args, **kwargs)
+#
+# # Set querysets based on tenant
+# if tenant:
+# from core.models import Department
+# self.fields['department'].queryset = Department.objects.filter(tenant=tenant)
+# self.fields['manager'].queryset = User.objects.filter(
+# tenant=tenant,
+# is_active=True,
+# groups__name__in=['Managers', 'Department Heads']
+# )
+#
+# # Crispy forms helper
+# self.helper = FormHelper()
+# self.helper.layout = Layout(
+# Fieldset(
+# 'User Information',
+# Row(
+# Column('first_name', css_class='form-group col-md-6 mb-0'),
+# Column('last_name', css_class='form-group col-md-6 mb-0'),
+# css_class='form-row'
+# ),
+# Row(
+# Column('username', css_class='form-group col-md-6 mb-0'),
+# Column('email', css_class='form-group col-md-6 mb-0'),
+# css_class='form-row'
+# ),
+# Row(
+# Column('employee_id', css_class='form-group col-md-6 mb-0'),
+# Column('phone_number', css_class='form-group col-md-6 mb-0'),
+# css_class='form-row'
+# )
+# ),
+# Fieldset(
+# 'Employment Information',
+# Row(
+# Column('department', css_class='form-group col-md-6 mb-0'),
+# Column('job_title', css_class='form-group col-md-6 mb-0'),
+# css_class='form-row'
+# ),
+# Row(
+# Column('start_date', css_class='form-group col-md-6 mb-0'),
+# Column('manager', css_class='form-group col-md-6 mb-0'),
+# css_class='form-row'
+# )
+# ),
+# Fieldset(
+# 'Security',
+# Row(
+# Column('password1', css_class='form-group col-md-6 mb-0'),
+# Column('password2', css_class='form-group col-md-6 mb-0'),
+# css_class='form-row'
+# )
+# ),
+# FormActions(
+# Submit('submit', 'Register User', css_class='btn btn-primary'),
+# HTML('Cancel')
+# )
+# )
+#
+# def clean_email(self):
+# email = self.cleaned_data.get('email')
+# if User.objects.filter(email=email).exists():
+# raise ValidationError('A user with this email already exists.')
+# return email
+#
+# def clean_employee_id(self):
+# employee_id = self.cleaned_data.get('employee_id')
+# if employee_id and User.objects.filter(employee_id=employee_id).exists():
+# raise ValidationError('A user with this employee ID already exists.')
+# return employee_id
+#
+#
+# class AccountActivationForm(forms.Form):
+# """
+# Form for account activation in onboarding workflow
+# """
+# activation_code = forms.CharField(
+# max_length=100,
+# required=True,
+# widget=forms.TextInput(attrs={'class': 'form-control'})
+# )
+# terms_accepted = forms.BooleanField(
+# required=True,
+# widget=forms.CheckboxInput(attrs={'class': 'form-check-input'})
+# )
+# privacy_policy_accepted = forms.BooleanField(
+# required=True,
+# widget=forms.CheckboxInput(attrs={'class': 'form-check-input'})
+# )
+#
+# def __init__(self, *args, **kwargs):
+# super().__init__(*args, **kwargs)
+#
+# self.helper = FormHelper()
+# self.helper.layout = Layout(
+# Fieldset(
+# 'Account Activation',
+# 'activation_code',
+# HTML('
'),
+# 'terms_accepted',
+# HTML(''),
+# HTML('
'),
+# HTML(''),
+# 'privacy_policy_accepted',
+# HTML(
+# ''),
+# HTML('
')
+# ),
+# FormActions(
+# Submit('submit', 'Activate Account', css_class='btn btn-primary'),
+# HTML('Cancel')
+# )
+# )
+#
+#
+# class TwoFactorSetupForm(forms.ModelForm):
+# """
+# Form for two-factor authentication setup
+# """
+# device_name = forms.CharField(
+# max_length=100,
+# required=True,
+# widget=forms.TextInput(attrs={'class': 'form-control'})
+# )
+# device_type = forms.ChoiceField(
+# choices=[
+# ('totp', 'Authenticator App (TOTP)'),
+# ('sms', 'SMS'),
+# ('email', 'Email'),
+# ('backup_codes', 'Backup Codes')
+# ],
+# required=True,
+# widget=forms.Select(attrs={'class': 'form-control'})
+# )
+# phone_number = forms.CharField(
+# max_length=20,
+# required=False,
+# widget=forms.TextInput(attrs={'class': 'form-control'})
+# )
+# verification_code = forms.CharField(
+# max_length=10,
+# required=True,
+# widget=forms.TextInput(attrs={'class': 'form-control'})
+# )
+#
+# class Meta:
+# model = TwoFactorDevice
+# fields = ['device_name', 'device_type', 'phone_number']
+#
+# def __init__(self, *args, **kwargs):
+# super().__init__(*args, **kwargs)
+#
+# self.helper = FormHelper()
+# self.helper.layout = Layout(
+# Fieldset(
+# 'Two-Factor Authentication Setup',
+# 'device_name',
+# 'device_type',
+# 'phone_number',
+# HTML(
+# 'Enter the verification code from your authenticator app or device.
'),
+# 'verification_code'
+# ),
+# FormActions(
+# Submit('submit', 'Setup Two-Factor Auth', css_class='btn btn-primary'),
+# HTML('Cancel')
+# )
+# )
+#
+# def clean(self):
+# cleaned_data = super().clean()
+# device_type = cleaned_data.get('device_type')
+# phone_number = cleaned_data.get('phone_number')
+#
+# if device_type == 'sms' and not phone_number:
+# raise ValidationError('Phone number is required for SMS two-factor authentication.')
+#
+# return cleaned_data
+#
+#
+# class PermissionManagementForm(forms.Form):
+# """
+# Form for managing user permissions
+# """
+# groups = forms.ModelMultipleChoiceField(
+# queryset=Group.objects.all(),
+# required=False,
+# widget=forms.CheckboxSelectMultiple(attrs={'class': 'form-check-input'})
+# )
+# is_staff = forms.BooleanField(
+# required=False,
+# widget=forms.CheckboxInput(attrs={'class': 'form-check-input'})
+# )
+# is_superuser = forms.BooleanField(
+# required=False,
+# widget=forms.CheckboxInput(attrs={'class': 'form-check-input'})
+# )
+# access_level = forms.ChoiceField(
+# choices=[
+# ('basic', 'Basic Access'),
+# ('standard', 'Standard Access'),
+# ('advanced', 'Advanced Access'),
+# ('admin', 'Administrator Access')
+# ],
+# required=True,
+# widget=forms.Select(attrs={'class': 'form-control'})
+# )
+# department_access = forms.ModelMultipleChoiceField(
+# queryset=None, # Will be set in __init__
+# required=False,
+# widget=forms.CheckboxSelectMultiple(attrs={'class': 'form-check-input'})
+# )
+#
+# def __init__(self, *args, **kwargs):
+# tenant = kwargs.pop('tenant', None)
+# super().__init__(*args, **kwargs)
+#
+# if tenant:
+# from core.models import Department
+# self.fields['department_access'].queryset = Department.objects.filter(tenant=tenant)
+#
+# self.helper = FormHelper()
+# self.helper.layout = Layout(
+# Fieldset(
+# 'User Permissions',
+# 'access_level',
+# HTML(''),
+# 'is_staff',
+# HTML(''),
+# HTML('
'),
+# HTML(''),
+# 'is_superuser',
+# HTML(''),
+# HTML('
')
+# ),
+# Fieldset(
+# 'Group Memberships',
+# 'groups'
+# ),
+# Fieldset(
+# 'Department Access',
+# 'department_access'
+# ),
+# FormActions(
+# Submit('submit', 'Update Permissions', css_class='btn btn-primary'),
+# HTML('Cancel')
+# )
+# )
+#
+#
+# class SecurityAuditForm(forms.Form):
+# """
+# Form for security audit configuration
+# """
+# audit_type = forms.ChoiceField(
+# choices=[
+# ('comprehensive', 'Comprehensive Security Audit'),
+# ('password_policy', 'Password Policy Audit'),
+# ('access_review', 'Access Rights Review'),
+# ('session_audit', 'Session Security Audit'),
+# ('two_factor_audit', 'Two-Factor Authentication Audit')
+# ],
+# required=True,
+# widget=forms.Select(attrs={'class': 'form-control'})
+# )
+# include_inactive_users = forms.BooleanField(
+# required=False,
+# widget=forms.CheckboxInput(attrs={'class': 'form-check-input'})
+# )
+# check_password_strength = forms.BooleanField(
+# required=False,
+# widget=forms.CheckboxInput(attrs={'class': 'form-check-input'})
+# )
+# review_login_attempts = forms.BooleanField(
+# required=False,
+# widget=forms.CheckboxInput(attrs={'class': 'form-check-input'})
+# )
+# analyze_session_security = forms.BooleanField(
+# required=False,
+# widget=forms.CheckboxInput(attrs={'class': 'form-check-input'})
+# )
+# generate_report = forms.BooleanField(
+# required=False,
+# initial=True,
+# widget=forms.CheckboxInput(attrs={'class': 'form-check-input'})
+# )
+#
+# def __init__(self, *args, **kwargs):
+# super().__init__(*args, **kwargs)
+#
+# self.helper = FormHelper()
+# self.helper.layout = Layout(
+# Fieldset(
+# 'Security Audit Configuration',
+# 'audit_type',
+# HTML(''),
+# 'include_inactive_users',
+# HTML(''),
+# HTML('
'),
+# HTML(''),
+# 'check_password_strength',
+# HTML(
+# ''),
+# HTML('
'),
+# HTML(''),
+# 'review_login_attempts',
+# HTML(''),
+# HTML('
'),
+# HTML(''),
+# 'analyze_session_security',
+# HTML(
+# ''),
+# HTML('
'),
+# HTML(''),
+# 'generate_report',
+# HTML(''),
+# HTML('
')
+# ),
+# FormActions(
+# Submit('submit', 'Start Security Audit', css_class='btn btn-primary'),
+# HTML('Cancel')
+# )
+# )
+#
+#
+# class SessionManagementForm(forms.Form):
+# """
+# Form for session management configuration
+# """
+# session_timeout = forms.IntegerField(
+# min_value=5,
+# max_value=1440,
+# initial=30,
+# widget=forms.NumberInput(attrs={'class': 'form-control'})
+# )
+# max_concurrent_sessions = forms.IntegerField(
+# min_value=1,
+# max_value=10,
+# initial=3,
+# widget=forms.NumberInput(attrs={'class': 'form-control'})
+# )
+# require_secure_cookies = forms.BooleanField(
+# required=False,
+# initial=True,
+# widget=forms.CheckboxInput(attrs={'class': 'form-check-input'})
+# )
+# enable_session_monitoring = forms.BooleanField(
+# required=False,
+# initial=True,
+# widget=forms.CheckboxInput(attrs={'class': 'form-check-input'})
+# )
+# log_session_events = forms.BooleanField(
+# required=False,
+# initial=True,
+# widget=forms.CheckboxInput(attrs={'class': 'form-check-input'})
+# )
+# auto_logout_inactive = forms.BooleanField(
+# required=False,
+# initial=True,
+# widget=forms.CheckboxInput(attrs={'class': 'form-check-input'})
+# )
+#
+# def __init__(self, *args, **kwargs):
+# super().__init__(*args, **kwargs)
+#
+# self.helper = FormHelper()
+# self.helper.layout = Layout(
+# Fieldset(
+# 'Session Configuration',
+# Row(
+# Column('session_timeout', css_class='form-group col-md-6 mb-0'),
+# Column('max_concurrent_sessions', css_class='form-group col-md-6 mb-0'),
+# css_class='form-row'
+# ),
+# HTML(''),
+# 'require_secure_cookies',
+# HTML(''),
+# HTML('
'),
+# HTML(''),
+# 'enable_session_monitoring',
+# HTML(
+# ''),
+# HTML('
'),
+# HTML(''),
+# 'log_session_events',
+# HTML(''),
+# HTML('
'),
+# HTML(''),
+# 'auto_logout_inactive',
+# HTML(
+# ''),
+# HTML('
')
+# ),
+# FormActions(
+# Submit('submit', 'Update Session Settings', css_class='btn btn-primary'),
+# HTML('Cancel')
+# )
+# )
+#
+#
+# class ComplianceCheckForm(forms.Form):
+# """
+# Form for compliance verification
+# """
+# compliance_standards = forms.MultipleChoiceField(
+# choices=[
+# ('hipaa', 'HIPAA Compliance'),
+# ('gdpr', 'GDPR Compliance'),
+# ('sox', 'SOX Compliance'),
+# ('pci_dss', 'PCI DSS Compliance'),
+# ('iso27001', 'ISO 27001 Compliance')
+# ],
+# required=True,
+# widget=forms.CheckboxSelectMultiple(attrs={'class': 'form-check-input'})
+# )
+# check_password_policies = forms.BooleanField(
+# required=False,
+# initial=True,
+# widget=forms.CheckboxInput(attrs={'class': 'form-check-input'})
+# )
+# verify_access_controls = forms.BooleanField(
+# required=False,
+# initial=True,
+# widget=forms.CheckboxInput(attrs={'class': 'form-check-input'})
+# )
+# audit_user_permissions = forms.BooleanField(
+# required=False,
+# initial=True,
+# widget=forms.CheckboxInput(attrs={'class': 'form-check-input'})
+# )
+# check_data_encryption = forms.BooleanField(
+# required=False,
+# initial=True,
+# widget=forms.CheckboxInput(attrs={'class': 'form-check-input'})
+# )
+# generate_compliance_report = forms.BooleanField(
+# required=False,
+# initial=True,
+# widget=forms.CheckboxInput(attrs={'class': 'form-check-input'})
+# )
+#
+# def __init__(self, *args, **kwargs):
+# super().__init__(*args, **kwargs)
+#
+# self.helper = FormHelper()
+# self.helper.layout = Layout(
+# Fieldset(
+# 'Compliance Standards',
+# 'compliance_standards'
+# ),
+# Fieldset(
+# 'Compliance Checks',
+# HTML(''),
+# 'check_password_policies',
+# HTML(
+# ''),
+# HTML('
'),
+# HTML(''),
+# 'verify_access_controls',
+# HTML(''),
+# HTML('
'),
+# HTML(''),
+# 'audit_user_permissions',
+# HTML(''),
+# HTML('
'),
+# HTML(''),
+# 'check_data_encryption',
+# HTML(''),
+# HTML('
'),
+# HTML(''),
+# 'generate_compliance_report',
+# HTML(
+# ''),
+# HTML('
')
+# ),
+# FormActions(
+# Submit('submit', 'Start Compliance Check', css_class='btn btn-primary'),
+# HTML('Cancel')
+# )
+# )
+#
+#
+# class AccountDeactivationForm(forms.Form):
+# """
+# Form for account deactivation
+# """
+# deactivation_reason = forms.ChoiceField(
+# choices=[
+# ('termination', 'Employment Termination'),
+# ('resignation', 'Employee Resignation'),
+# ('transfer', 'Department Transfer'),
+# ('leave', 'Extended Leave'),
+# ('security', 'Security Concerns'),
+# ('other', 'Other Reason')
+# ],
+# required=True,
+# widget=forms.Select(attrs={'class': 'form-control'})
+# )
+# deactivation_date = forms.DateField(
+# required=True,
+# initial=timezone.now().date(),
+# widget=forms.DateInput(attrs={'class': 'form-control', 'type': 'date'})
+# )
+# backup_data = forms.BooleanField(
+# required=False,
+# initial=True,
+# widget=forms.CheckboxInput(attrs={'class': 'form-check-input'})
+# )
+# transfer_ownership = forms.BooleanField(
+# required=False,
+# widget=forms.CheckboxInput(attrs={'class': 'form-check-input'})
+# )
+# new_owner = forms.ModelChoiceField(
+# queryset=None, # Will be set in __init__
+# required=False,
+# widget=forms.Select(attrs={'class': 'form-control'})
+# )
+# notify_stakeholders = forms.BooleanField(
+# required=False,
+# initial=True,
+# widget=forms.CheckboxInput(attrs={'class': 'form-check-input'})
+# )
+# additional_notes = forms.CharField(
+# required=False,
+# widget=forms.Textarea(attrs={'class': 'form-control', 'rows': 4})
+# )
+#
+# def __init__(self, *args, **kwargs):
+# tenant = kwargs.pop('tenant', None)
+# super().__init__(*args, **kwargs)
+#
+# if tenant:
+# self.fields['new_owner'].queryset = User.objects.filter(
+# tenant=tenant,
+# is_active=True
+# ).exclude(id=self.instance.id if hasattr(self, 'instance') else None)
+#
+# self.helper = FormHelper()
+# self.helper.layout = Layout(
+# Fieldset(
+# 'Deactivation Details',
+# Row(
+# Column('deactivation_reason', css_class='form-group col-md-6 mb-0'),
+# Column('deactivation_date', css_class='form-group col-md-6 mb-0'),
+# css_class='form-row'
+# ),
+# 'additional_notes'
+# ),
+# Fieldset(
+# 'Data Management',
+# HTML(''),
+# 'backup_data',
+# HTML(''),
+# HTML('
'),
+# HTML(''),
+# 'transfer_ownership',
+# HTML(''),
+# HTML('
'),
+# 'new_owner'
+# ),
+# Fieldset(
+# 'Notifications',
+# HTML(''),
+# 'notify_stakeholders',
+# HTML(''),
+# HTML('
')
+# ),
+# FormActions(
+# Submit('submit', 'Deactivate Account', css_class='btn btn-danger'),
+# HTML('Cancel')
+# )
+# )
+#
+# def clean(self):
+# cleaned_data = super().clean()
+# transfer_ownership = cleaned_data.get('transfer_ownership')
+# new_owner = cleaned_data.get('new_owner')
+#
+# if transfer_ownership and not new_owner:
+# raise ValidationError('New owner must be selected when transferring ownership.')
+#
+# return cleaned_data
+#
+#
+# class PasswordResetForm(forms.Form):
+# """
+# Form for password reset
+# """
+# email = forms.EmailField(
+# required=True,
+# widget=forms.EmailInput(attrs={'class': 'form-control'})
+# )
+#
+# def __init__(self, *args, **kwargs):
+# super().__init__(*args, **kwargs)
+#
+# self.helper = FormHelper()
+# self.helper.layout = Layout(
+# Fieldset(
+# 'Password Reset',
+# 'email',
+# HTML(
+# 'Enter your email address and we will send you a link to reset your password.
')
+# ),
+# FormActions(
+# Submit('submit', 'Send Reset Link', css_class='btn btn-primary'),
+# HTML('Back to Login')
+# )
+# )
+#
+# def clean_email(self):
+# email = self.cleaned_data.get('email')
+# if not User.objects.filter(email=email, is_active=True).exists():
+# raise ValidationError('No active user found with this email address.')
+# return email
+#
+#
+# class PasswordChangeForm(PasswordChangeForm):
+# """
+# Enhanced password change form
+# """
+#
+# def __init__(self, *args, **kwargs):
+# super().__init__(*args, **kwargs)
+#
+# # Add CSS classes
+# for field in self.fields.values():
+# field.widget.attrs['class'] = 'form-control'
+#
+# self.helper = FormHelper()
+# self.helper.layout = Layout(
+# Fieldset(
+# 'Change Password',
+# 'old_password',
+# 'new_password1',
+# 'new_password2',
+# HTML(
+# 'Your password must contain at least 8 characters and cannot be too similar to your other personal information.
')
+# ),
+# FormActions(
+# Submit('submit', 'Change Password', css_class='btn btn-primary'),
+# HTML('Cancel')
+# )
+# )
+#
diff --git a/accounts/views.py b/accounts/views.py
index 5a14c533..615079e8 100644
--- a/accounts/views.py
+++ b/accounts/views.py
@@ -2474,3 +2474,650 @@ def upload_avatar(request, pk):
#
#
#
+# from django.shortcuts import render, redirect, get_object_or_404
+# from django.contrib.auth import login, logout, authenticate
+# from django.contrib.auth.decorators import login_required, permission_required
+# from django.contrib.auth.mixins import LoginRequiredMixin, PermissionRequiredMixin
+# from django.contrib import messages
+# from django.views.generic import (
+# CreateView, UpdateView, DeleteView, DetailView, ListView, FormView
+# )
+# from django.urls import reverse_lazy, reverse
+# from django.http import JsonResponse, HttpResponse
+# from django.utils import timezone
+# from django.db import transaction, models
+# from django.core.mail import send_mail
+# from django.conf import settings
+# from django.contrib.auth.models import Group
+# from viewflow.workflow.flow.views import CreateProcessView, UpdateProcessView
+#
+# from .models import User, TwoFactorDevice, SocialAccount, UserSession, PasswordHistory
+# from .forms import (
+# UserRegistrationForm, AccountActivationForm, TwoFactorSetupForm,
+# PermissionManagementForm, SecurityAuditForm, SessionManagementForm,
+# ComplianceCheckForm, AccountDeactivationForm, PasswordResetForm,
+# PasswordChangeForm
+# )
+# from .flows import UserOnboardingFlow, SecurityManagementFlow, AccountDeactivationFlow
+#
+#
+# class UserRegistrationView(LoginRequiredMixin, PermissionRequiredMixin, CreateProcessView):
+# """
+# View for user registration in onboarding workflow
+# """
+# model = User
+# form_class = UserRegistrationForm
+# template_name = 'accounts/user_registration.html'
+# permission_required = 'accounts.can_register_users'
+# flow_class = UserOnboardingFlow
+#
+# def get_form_kwargs(self):
+# kwargs = super().get_form_kwargs()
+# kwargs['tenant'] = self.request.user.tenant
+# return kwargs
+#
+# def form_valid(self, form):
+# with transaction.atomic():
+# # Create user
+# user = form.save(commit=False)
+# user.tenant = self.request.user.tenant
+# user.is_active = False # Will be activated in workflow
+# user.created_by = self.request.user
+# user.save()
+#
+# # Start onboarding workflow
+# process = self.flow_class.start.run(
+# user=user,
+# created_by=self.request.user
+# )
+#
+# messages.success(
+# self.request,
+# f'User registration initiated for {user.get_full_name()}. '
+# f'Onboarding workflow started.'
+# )
+#
+# return redirect('accounts:user_detail', pk=user.pk)
+#
+# def get_context_data(self, **kwargs):
+# context = super().get_context_data(**kwargs)
+# context['title'] = 'Register New User'
+# context['breadcrumbs'] = [
+# {'name': 'Home', 'url': reverse('core:dashboard')},
+# {'name': 'Users', 'url': reverse('accounts:user_list')},
+# {'name': 'Register User', 'url': ''}
+# ]
+# return context
+#
+#
+# class AccountActivationView(LoginRequiredMixin, PermissionRequiredMixin, FormView):
+# """
+# View for account activation in onboarding workflow
+# """
+# form_class = AccountActivationForm
+# template_name = 'accounts/account_activation.html'
+# permission_required = 'accounts.can_activate_accounts'
+#
+# def get_success_url(self):
+# return reverse('accounts:user_detail', kwargs={'pk': self.kwargs['pk']})
+#
+# def form_valid(self, form):
+# user = get_object_or_404(User, pk=self.kwargs['pk'])
+# activation_code = form.cleaned_data['activation_code']
+#
+# # Verify activation code (implement your verification logic)
+# if self.verify_activation_code(user, activation_code):
+# user.is_active = True
+# user.email_verified = True
+# user.activated_at = timezone.now()
+# user.save()
+#
+# # Send welcome email
+# self.send_welcome_email(user)
+#
+# messages.success(
+# self.request,
+# f'Account activated successfully for {user.get_full_name()}.'
+# )
+# else:
+# messages.error(self.request, 'Invalid activation code.')
+# return self.form_invalid(form)
+#
+# return super().form_valid(form)
+#
+# def verify_activation_code(self, user, code):
+# """Verify activation code (implement your logic)"""
+# # This would implement actual verification logic
+# return True
+#
+# def send_welcome_email(self, user):
+# """Send welcome email to activated user"""
+# if user.email:
+# send_mail(
+# subject='Welcome to Hospital Management System',
+# message=f'Welcome {user.get_full_name()}! Your account has been activated.',
+# from_email=settings.DEFAULT_FROM_EMAIL,
+# recipient_list=[user.email],
+# fail_silently=True
+# )
+#
+# def get_context_data(self, **kwargs):
+# context = super().get_context_data(**kwargs)
+# context['user'] = get_object_or_404(User, pk=self.kwargs['pk'])
+# context['title'] = 'Activate Account'
+# return context
+#
+#
+# class TwoFactorSetupView(LoginRequiredMixin, PermissionRequiredMixin, CreateView):
+# """
+# View for two-factor authentication setup
+# """
+# model = TwoFactorDevice
+# form_class = TwoFactorSetupForm
+# template_name = 'accounts/two_factor_setup.html'
+# permission_required = 'accounts.can_setup_two_factor'
+#
+# def get_success_url(self):
+# return reverse('accounts:security_settings')
+#
+# def form_valid(self, form):
+# device = form.save(commit=False)
+# device.user = self.request.user
+# device.is_active = True
+# device.created_at = timezone.now()
+#
+# # Generate device-specific configuration
+# device.configuration = self.generate_device_config(device.device_type)
+# device.save()
+#
+# messages.success(
+# self.request,
+# 'Two-factor authentication has been set up successfully.'
+# )
+#
+# return super().form_valid(form)
+#
+# def generate_device_config(self, device_type):
+# """Generate device-specific configuration"""
+# if device_type == 'totp':
+# # Generate TOTP secret
+# import pyotp
+# return {'secret': pyotp.random_base32()}
+# elif device_type == 'backup_codes':
+# # Generate backup codes
+# import secrets
+# codes = [secrets.token_hex(4) for _ in range(10)]
+# return {'codes': codes}
+# return {}
+#
+# def get_context_data(self, **kwargs):
+# context = super().get_context_data(**kwargs)
+# context['title'] = 'Setup Two-Factor Authentication'
+# return context
+#
+#
+# class PermissionManagementView(LoginRequiredMixin, PermissionRequiredMixin, FormView):
+# """
+# View for managing user permissions
+# """
+# form_class = PermissionManagementForm
+# template_name = 'accounts/permission_management.html'
+# permission_required = 'accounts.can_manage_permissions'
+#
+# def get_success_url(self):
+# return reverse('accounts:user_detail', kwargs={'pk': self.kwargs['pk']})
+#
+# def get_form_kwargs(self):
+# kwargs = super().get_form_kwargs()
+# kwargs['tenant'] = self.request.user.tenant
+# return kwargs
+#
+# def get_initial(self):
+# user = get_object_or_404(User, pk=self.kwargs['pk'])
+# return {
+# 'groups': user.groups.all(),
+# 'is_staff': user.is_staff,
+# 'is_superuser': user.is_superuser,
+# 'access_level': getattr(user, 'access_level', 'basic'),
+# 'department_access': getattr(user, 'department_access', [])
+# }
+#
+# def form_valid(self, form):
+# user = get_object_or_404(User, pk=self.kwargs['pk'])
+#
+# with transaction.atomic():
+# # Update user permissions
+# user.groups.set(form.cleaned_data['groups'])
+# user.is_staff = form.cleaned_data['is_staff']
+# user.is_superuser = form.cleaned_data['is_superuser']
+# user.access_level = form.cleaned_data['access_level']
+# user.save()
+#
+# # Log permission changes
+# self.log_permission_changes(user, form.cleaned_data)
+#
+# messages.success(
+# self.request,
+# f'Permissions updated successfully for {user.get_full_name()}.'
+# )
+#
+# return super().form_valid(form)
+#
+# def log_permission_changes(self, user, changes):
+# """Log permission changes for audit"""
+# from core.models import AuditLogEntry
+# AuditLogEntry.objects.create(
+# tenant=user.tenant,
+# user=self.request.user,
+# event_type='PERMISSION_CHANGE',
+# action='UPDATE',
+# object_type='User',
+# object_id=str(user.id),
+# details=changes,
+# ip_address=self.request.META.get('REMOTE_ADDR'),
+# user_agent=self.request.META.get('HTTP_USER_AGENT', '')
+# )
+#
+# def get_context_data(self, **kwargs):
+# context = super().get_context_data(**kwargs)
+# context['user'] = get_object_or_404(User, pk=self.kwargs['pk'])
+# context['title'] = 'Manage Permissions'
+# return context
+#
+#
+# class SecurityAuditView(LoginRequiredMixin, PermissionRequiredMixin, FormView):
+# """
+# View for security audit configuration
+# """
+# form_class = SecurityAuditForm
+# template_name = 'accounts/security_audit.html'
+# permission_required = 'accounts.can_audit_security'
+#
+# def get_success_url(self):
+# return reverse('accounts:security_dashboard')
+#
+# def form_valid(self, form):
+# audit_config = form.cleaned_data
+#
+# # Start security audit workflow
+# process = SecurityManagementFlow.start.run(
+# user=self.request.user,
+# audit_config=audit_config,
+# created_by=self.request.user
+# )
+#
+# messages.success(
+# self.request,
+# 'Security audit has been initiated. You will receive a notification when complete.'
+# )
+#
+# return super().form_valid(form)
+#
+# def get_context_data(self, **kwargs):
+# context = super().get_context_data(**kwargs)
+# context['title'] = 'Security Audit'
+# context['recent_audits'] = self.get_recent_audits()
+# return context
+#
+# def get_recent_audits(self):
+# """Get recent security audits"""
+# # This would return recent audit records
+# return []
+#
+#
+# class SessionManagementView(LoginRequiredMixin, PermissionRequiredMixin, FormView):
+# """
+# View for session management configuration
+# """
+# form_class = SessionManagementForm
+# template_name = 'accounts/session_management.html'
+# permission_required = 'accounts.can_manage_sessions'
+#
+# def get_success_url(self):
+# return reverse('accounts:security_settings')
+#
+# def get_initial(self):
+# # Get current session settings
+# return {
+# 'session_timeout': getattr(settings, 'SESSION_COOKIE_AGE', 1800) // 60,
+# 'max_concurrent_sessions': 3,
+# 'require_secure_cookies': getattr(settings, 'SESSION_COOKIE_SECURE', True),
+# 'enable_session_monitoring': True,
+# 'log_session_events': True,
+# 'auto_logout_inactive': True
+# }
+#
+# def form_valid(self, form):
+# config = form.cleaned_data
+#
+# # Update session configuration
+# self.update_session_config(config)
+#
+# messages.success(
+# self.request,
+# 'Session management settings updated successfully.'
+# )
+#
+# return super().form_valid(form)
+#
+# def update_session_config(self, config):
+# """Update session configuration"""
+# # This would update session configuration
+# pass
+#
+# def get_context_data(self, **kwargs):
+# context = super().get_context_data(**kwargs)
+# context['title'] = 'Session Management'
+# context['active_sessions'] = self.get_active_sessions()
+# return context
+#
+# def get_active_sessions(self):
+# """Get active user sessions"""
+# return UserSession.objects.filter(
+# user=self.request.user,
+# is_active=True
+# ).order_by('-created_at')
+#
+#
+# class ComplianceCheckView(LoginRequiredMixin, PermissionRequiredMixin, FormView):
+# """
+# View for compliance verification
+# """
+# form_class = ComplianceCheckForm
+# template_name = 'accounts/compliance_check.html'
+# permission_required = 'accounts.can_verify_compliance'
+#
+# def get_success_url(self):
+# return reverse('accounts:compliance_dashboard')
+#
+# def form_valid(self, form):
+# compliance_config = form.cleaned_data
+#
+# # Start compliance check
+# self.start_compliance_check(compliance_config)
+#
+# messages.success(
+# self.request,
+# 'Compliance check has been initiated. Results will be available shortly.'
+# )
+#
+# return super().form_valid(form)
+#
+# def start_compliance_check(self, config):
+# """Start compliance verification process"""
+# # This would start compliance checking
+# pass
+#
+# def get_context_data(self, **kwargs):
+# context = super().get_context_data(**kwargs)
+# context['title'] = 'Compliance Check'
+# context['compliance_status'] = self.get_compliance_status()
+# return context
+#
+# def get_compliance_status(self):
+# """Get current compliance status"""
+# return {
+# 'hipaa': 'compliant',
+# 'gdpr': 'compliant',
+# 'sox': 'pending',
+# 'pci_dss': 'non_compliant',
+# 'iso27001': 'compliant'
+# }
+#
+#
+# class AccountDeactivationView(LoginRequiredMixin, PermissionRequiredMixin, FormView):
+# """
+# View for account deactivation
+# """
+# form_class = AccountDeactivationForm
+# template_name = 'accounts/account_deactivation.html'
+# permission_required = 'accounts.can_deactivate_accounts'
+#
+# def get_success_url(self):
+# return reverse('accounts:user_list')
+#
+# def get_form_kwargs(self):
+# kwargs = super().get_form_kwargs()
+# kwargs['tenant'] = self.request.user.tenant
+# return kwargs
+#
+# def form_valid(self, form):
+# user = get_object_or_404(User, pk=self.kwargs['pk'])
+# deactivation_config = form.cleaned_data
+#
+# # Start account deactivation workflow
+# process = AccountDeactivationFlow.start.run(
+# user=user,
+# deactivation_config=deactivation_config,
+# created_by=self.request.user
+# )
+#
+# messages.success(
+# self.request,
+# f'Account deactivation initiated for {user.get_full_name()}.'
+# )
+#
+# return super().form_valid(form)
+#
+# def get_context_data(self, **kwargs):
+# context = super().get_context_data(**kwargs)
+# context['user'] = get_object_or_404(User, pk=self.kwargs['pk'])
+# context['title'] = 'Deactivate Account'
+# return context
+#
+#
+# class UserListView(LoginRequiredMixin, PermissionRequiredMixin, ListView):
+# """
+# View for listing users
+# """
+# model = User
+# template_name = 'accounts/user_list.html'
+# context_object_name = 'users'
+# permission_required = 'accounts.view_user'
+# paginate_by = 25
+#
+# def get_queryset(self):
+# queryset = User.objects.filter(tenant=self.request.user.tenant)
+#
+# # Apply filters
+# search = self.request.GET.get('search')
+# if search:
+# queryset = queryset.filter(
+# models.Q(first_name__icontains=search) |
+# models.Q(last_name__icontains=search) |
+# models.Q(email__icontains=search) |
+# models.Q(username__icontains=search)
+# )
+#
+# department = self.request.GET.get('department')
+# if department:
+# queryset = queryset.filter(department_id=department)
+#
+# status = self.request.GET.get('status')
+# if status == 'active':
+# queryset = queryset.filter(is_active=True)
+# elif status == 'inactive':
+# queryset = queryset.filter(is_active=False)
+#
+# return queryset.order_by('last_name', 'first_name')
+#
+# def get_context_data(self, **kwargs):
+# context = super().get_context_data(**kwargs)
+# context['title'] = 'Users'
+# context['departments'] = self.get_departments()
+# context['search'] = self.request.GET.get('search', '')
+# context['selected_department'] = self.request.GET.get('department', '')
+# context['selected_status'] = self.request.GET.get('status', '')
+# return context
+#
+# def get_departments(self):
+# """Get departments for filter"""
+# from core.models import Department
+# return Department.objects.filter(tenant=self.request.user.tenant)
+#
+#
+# class UserDetailView(LoginRequiredMixin, PermissionRequiredMixin, DetailView):
+# """
+# View for user details
+# """
+# model = User
+# template_name = 'accounts/user_detail.html'
+# context_object_name = 'user'
+# permission_required = 'accounts.view_user'
+#
+# def get_queryset(self):
+# return User.objects.filter(tenant=self.request.user.tenant)
+#
+# def get_context_data(self, **kwargs):
+# context = super().get_context_data(**kwargs)
+# user = self.object
+# context['title'] = f'{user.get_full_name()}'
+# context['two_factor_devices'] = user.two_factor_devices.filter(is_active=True)
+# context['recent_sessions'] = user.user_sessions.order_by('-created_at')[:5]
+# context['password_history'] = user.password_history.order_by('-created_at')[:5]
+# return context
+#
+#
+# class SecurityDashboardView(LoginRequiredMixin, PermissionRequiredMixin, ListView):
+# """
+# View for security dashboard
+# """
+# template_name = 'accounts/security_dashboard.html'
+# permission_required = 'accounts.view_security_dashboard'
+#
+# def get_queryset(self):
+# return None
+#
+# def get_context_data(self, **kwargs):
+# context = super().get_context_data(**kwargs)
+# context['title'] = 'Security Dashboard'
+# context['security_metrics'] = self.get_security_metrics()
+# context['recent_alerts'] = self.get_recent_security_alerts()
+# context['compliance_status'] = self.get_compliance_status()
+# return context
+#
+# def get_security_metrics(self):
+# """Get security metrics"""
+# tenant = self.request.user.tenant
+# return {
+# 'total_users': User.objects.filter(tenant=tenant).count(),
+# 'active_users': User.objects.filter(tenant=tenant, is_active=True).count(),
+# 'users_with_2fa': User.objects.filter(
+# tenant=tenant,
+# two_factor_devices__is_active=True
+# ).distinct().count(),
+# 'failed_logins_today': 0, # Would be calculated from audit logs
+# 'password_expiring_soon': 0 # Would be calculated from password history
+# }
+#
+# def get_recent_security_alerts(self):
+# """Get recent security alerts"""
+# # This would return recent security alerts
+# return []
+#
+# def get_compliance_status(self):
+# """Get compliance status"""
+# return {
+# 'hipaa': 'compliant',
+# 'gdpr': 'compliant',
+# 'sox': 'pending',
+# 'pci_dss': 'non_compliant',
+# 'iso27001': 'compliant'
+# }
+#
+#
+# # AJAX Views
+# @login_required
+# @permission_required('accounts.can_manage_sessions')
+# def terminate_session_ajax(request, session_id):
+# """AJAX view to terminate user session"""
+# if request.method == 'POST':
+# try:
+# session = UserSession.objects.get(
+# id=session_id,
+# user__tenant=request.user.tenant
+# )
+# session.end_session()
+#
+# return JsonResponse({
+# 'success': True,
+# 'message': 'Session terminated successfully.'
+# })
+# except UserSession.DoesNotExist:
+# return JsonResponse({
+# 'success': False,
+# 'message': 'Session not found.'
+# })
+#
+# return JsonResponse({'success': False, 'message': 'Invalid request.'})
+#
+#
+# @login_required
+# @permission_required('accounts.can_reset_passwords')
+# def reset_password_ajax(request, user_id):
+# """AJAX view to reset user password"""
+# if request.method == 'POST':
+# try:
+# user = User.objects.get(
+# id=user_id,
+# tenant=request.user.tenant
+# )
+#
+# # Generate temporary password
+# import secrets
+# temp_password = secrets.token_urlsafe(12)
+# user.set_password(temp_password)
+# user.must_change_password = True
+# user.save()
+#
+# # Send password reset email
+# send_mail(
+# subject='Password Reset',
+# message=f'Your temporary password is: {temp_password}',
+# from_email=settings.DEFAULT_FROM_EMAIL,
+# recipient_list=[user.email],
+# fail_silently=True
+# )
+#
+# return JsonResponse({
+# 'success': True,
+# 'message': 'Password reset successfully. User will receive email with temporary password.'
+# })
+# except User.DoesNotExist:
+# return JsonResponse({
+# 'success': False,
+# 'message': 'User not found.'
+# })
+#
+# return JsonResponse({'success': False, 'message': 'Invalid request.'})
+#
+#
+# @login_required
+# def user_search_ajax(request):
+# """AJAX view for user search"""
+# query = request.GET.get('q', '')
+# if len(query) < 2:
+# return JsonResponse({'users': []})
+#
+# users = User.objects.filter(
+# tenant=request.user.tenant,
+# is_active=True
+# ).filter(
+# models.Q(first_name__icontains=query) |
+# models.Q(last_name__icontains=query) |
+# models.Q(email__icontains=query) |
+# models.Q(username__icontains=query)
+# )[:10]
+#
+# user_data = [
+# {
+# 'id': user.id,
+# 'name': user.get_full_name(),
+# 'email': user.email,
+# 'department': user.department.name if user.department else ''
+# }
+# for user in users
+# ]
+#
+# return JsonResponse({'users': user_data})
+#
diff --git a/analytics/.DS_Store b/analytics/.DS_Store
new file mode 100644
index 00000000..5008ddfc
Binary files /dev/null and b/analytics/.DS_Store differ
diff --git a/analytics/__pycache__/flows.cpython-312.pyc b/analytics/__pycache__/flows.cpython-312.pyc
new file mode 100644
index 00000000..7b7b8cbe
Binary files /dev/null and b/analytics/__pycache__/flows.cpython-312.pyc differ
diff --git a/analytics/__pycache__/forms.cpython-312.pyc b/analytics/__pycache__/forms.cpython-312.pyc
index bb5f696e..f0ac9348 100644
Binary files a/analytics/__pycache__/forms.cpython-312.pyc and b/analytics/__pycache__/forms.cpython-312.pyc differ
diff --git a/analytics/__pycache__/views.cpython-312.pyc b/analytics/__pycache__/views.cpython-312.pyc
index 68873074..671641a4 100644
Binary files a/analytics/__pycache__/views.cpython-312.pyc and b/analytics/__pycache__/views.cpython-312.pyc differ
diff --git a/analytics/flows.py b/analytics/flows.py
new file mode 100644
index 00000000..136b6467
--- /dev/null
+++ b/analytics/flows.py
@@ -0,0 +1,845 @@
+# """
+# Viewflow workflows for analytics app.
+# Provides report generation, dashboard management, and data analysis workflows.
+# """
+#
+# from viewflow import Flow, lock
+# from viewflow.base import this, flow_func
+# from viewflow.contrib import celery
+# from viewflow.decorators import flow_view
+# from viewflow.fields import CharField, ModelField
+# from viewflow.forms import ModelForm
+# from viewflow.views import CreateProcessView, UpdateProcessView
+# from viewflow.models import Process, Task
+# from django.contrib.auth.models import User
+# from django.urls import reverse_lazy
+# from django.utils import timezone
+# from django.db import transaction
+# from django.core.mail import send_mail
+#
+# from .models import Dashboard, DashboardWidget, DataSource, Report, ReportExecution, MetricDefinition, MetricValue
+# from .views import (
+# ReportGenerationView, DashboardCreationView, DataSourceConfigurationView,
+# MetricCalculationView, AnalysisView, VisualizationView, DistributionView,
+# SchedulingView, QualityAssuranceView, PerformanceOptimizationView
+# )
+#
+#
+# class ReportGenerationProcess(Process):
+# """
+# Viewflow process model for report generation
+# """
+# report = ModelField(Report, help_text='Associated report')
+#
+# # Process status tracking
+# report_requested = models.BooleanField(default=False)
+# data_extracted = models.BooleanField(default=False)
+# data_processed = models.BooleanField(default=False)
+# report_generated = models.BooleanField(default=False)
+# quality_checked = models.BooleanField(default=False)
+# report_distributed = models.BooleanField(default=False)
+# generation_completed = models.BooleanField(default=False)
+#
+# class Meta:
+# verbose_name = 'Report Generation Process'
+# verbose_name_plural = 'Report Generation Processes'
+#
+#
+# class ReportGenerationFlow(Flow):
+# """
+# Report Generation Workflow
+#
+# This flow manages automated report generation including
+# data extraction, processing, quality checks, and distribution.
+# """
+#
+# process_class = ReportGenerationProcess
+#
+# # Flow definition
+# start = (
+# flow_func(this.start_report_generation)
+# .Next(this.request_report)
+# )
+#
+# request_report = (
+# flow_view(ReportGenerationView)
+# .Permission('analytics.can_generate_reports')
+# .Next(this.extract_data)
+# )
+#
+# extract_data = (
+# flow_func(this.perform_data_extraction)
+# .Next(this.process_data)
+# )
+#
+# process_data = (
+# flow_func(this.perform_data_processing)
+# .Next(this.generate_report)
+# )
+#
+# generate_report = (
+# flow_func(this.create_report_output)
+# .Next(this.check_quality)
+# )
+#
+# check_quality = (
+# flow_view(QualityAssuranceView)
+# .Permission('analytics.can_check_quality')
+# .Next(this.distribute_report)
+# )
+#
+# distribute_report = (
+# flow_view(DistributionView)
+# .Permission('analytics.can_distribute_reports')
+# .Next(this.complete_generation)
+# )
+#
+# complete_generation = (
+# flow_func(this.finalize_report_generation)
+# .Next(this.end)
+# )
+#
+# end = flow_func(this.end_report_generation)
+#
+# # Flow functions
+# def start_report_generation(self, activation):
+# """Initialize the report generation process"""
+# process = activation.process
+# report = process.report
+#
+# # Create report execution record
+# execution = ReportExecution.objects.create(
+# report=report,
+# execution_type='MANUAL',
+# status='PENDING'
+# )
+#
+# # Send generation notification
+# self.notify_generation_start(report, execution)
+#
+# def perform_data_extraction(self, activation):
+# """Extract data from configured sources"""
+# process = activation.process
+# report = process.report
+#
+# # Extract data from all configured sources
+# extracted_data = self.extract_report_data(report)
+#
+# # Mark data extracted
+# process.data_extracted = True
+# process.save()
+#
+# # Store extracted data
+# self.store_extracted_data(report, extracted_data)
+#
+# def perform_data_processing(self, activation):
+# """Process and transform extracted data"""
+# process = activation.process
+# report = process.report
+#
+# # Process data according to report configuration
+# processed_data = self.process_report_data(report)
+#
+# # Mark data processed
+# process.data_processed = True
+# process.save()
+#
+# # Store processed data
+# self.store_processed_data(report, processed_data)
+#
+# def create_report_output(self, activation):
+# """Generate report output in specified format"""
+# process = activation.process
+# report = process.report
+#
+# # Generate report in configured format
+# report_output = self.generate_report_output(report)
+#
+# # Mark report generated
+# process.report_generated = True
+# process.save()
+#
+# # Store report output
+# self.store_report_output(report, report_output)
+#
+# def finalize_report_generation(self, activation):
+# """Finalize the report generation process"""
+# process = activation.process
+# report = process.report
+#
+# # Update report execution status
+# execution = ReportExecution.objects.filter(
+# report=report,
+# status='RUNNING'
+# ).first()
+#
+# if execution:
+# execution.status = 'COMPLETED'
+# execution.completed_at = timezone.now()
+# execution.save()
+#
+# # Mark generation completed
+# process.generation_completed = True
+# process.save()
+#
+# # Send completion notifications
+# self.notify_generation_completion(report)
+#
+# # Schedule next execution if recurring
+# self.schedule_next_execution(report)
+#
+# def end_report_generation(self, activation):
+# """End the report generation workflow"""
+# process = activation.process
+#
+# # Generate generation summary
+# self.generate_generation_summary(process.report)
+#
+# # Helper methods
+# def notify_generation_start(self, report, execution):
+# """Notify report generation start"""
+# analytics_team = User.objects.filter(groups__name='Analytics Team')
+# for staff in analytics_team:
+# send_mail(
+# subject=f'Report Generation Started: {report.name}',
+# message=f'Report generation process started for "{report.name}".',
+# from_email='analytics@hospital.com',
+# recipient_list=[staff.email],
+# fail_silently=True
+# )
+#
+# def extract_report_data(self, report):
+# """Extract data from report sources"""
+# # This would implement data extraction logic
+# return {'status': 'extracted', 'records': 1000}
+#
+# def store_extracted_data(self, report, data):
+# """Store extracted data"""
+# # This would store extracted data
+# pass
+#
+# def process_report_data(self, report):
+# """Process and transform report data"""
+# # This would implement data processing logic
+# return {'status': 'processed', 'records': 1000}
+#
+# def store_processed_data(self, report, data):
+# """Store processed data"""
+# # This would store processed data
+# pass
+#
+# def generate_report_output(self, report):
+# """Generate report output"""
+# # This would generate report in specified format
+# return {'status': 'generated', 'file_path': '/reports/output.pdf'}
+#
+# def store_report_output(self, report, output):
+# """Store report output"""
+# # This would store report output
+# pass
+#
+# def notify_generation_completion(self, report):
+# """Notify report generation completion"""
+# # Notify report subscribers
+# for subscriber in report.subscribers.all():
+# if subscriber.email:
+# send_mail(
+# subject=f'Report Ready: {report.name}',
+# message=f'Your report "{report.name}" is ready for download.',
+# from_email='analytics@hospital.com',
+# recipient_list=[subscriber.email],
+# fail_silently=True
+# )
+#
+# def schedule_next_execution(self, report):
+# """Schedule next report execution if recurring"""
+# if report.is_scheduled and report.schedule_config:
+# # Schedule next execution
+# schedule_report_execution.apply_async(
+# args=[report.report_id],
+# countdown=report.schedule_config.get('interval', 86400)
+# )
+#
+# def generate_generation_summary(self, report):
+# """Generate report generation summary"""
+# # This would generate generation summary
+# pass
+#
+#
+# class DashboardManagementProcess(Process):
+# """
+# Viewflow process model for dashboard management
+# """
+# dashboard = ModelField(Dashboard, help_text='Associated dashboard')
+#
+# # Process status tracking
+# dashboard_requested = models.BooleanField(default=False)
+# data_sources_configured = models.BooleanField(default=False)
+# widgets_created = models.BooleanField(default=False)
+# layout_configured = models.BooleanField(default=False)
+# permissions_set = models.BooleanField(default=False)
+# dashboard_tested = models.BooleanField(default=False)
+# dashboard_deployed = models.BooleanField(default=False)
+# management_completed = models.BooleanField(default=False)
+#
+# class Meta:
+# verbose_name = 'Dashboard Management Process'
+# verbose_name_plural = 'Dashboard Management Processes'
+#
+#
+# class DashboardManagementFlow(Flow):
+# """
+# Dashboard Management Workflow
+#
+# This flow manages dashboard creation, configuration,
+# and deployment including widgets and data sources.
+# """
+#
+# process_class = DashboardManagementProcess
+#
+# # Flow definition
+# start = (
+# flow_func(this.start_dashboard_management)
+# .Next(this.request_dashboard)
+# )
+#
+# request_dashboard = (
+# flow_view(DashboardCreationView)
+# .Permission('analytics.can_create_dashboards')
+# .Next(this.configure_data_sources)
+# )
+#
+# configure_data_sources = (
+# flow_view(DataSourceConfigurationView)
+# .Permission('analytics.can_configure_data_sources')
+# .Next(this.create_widgets)
+# )
+#
+# create_widgets = (
+# flow_func(this.setup_dashboard_widgets)
+# .Next(this.configure_layout)
+# )
+#
+# configure_layout = (
+# flow_func(this.setup_dashboard_layout)
+# .Next(this.set_permissions)
+# )
+#
+# set_permissions = (
+# flow_func(this.configure_dashboard_permissions)
+# .Next(this.test_dashboard)
+# )
+#
+# test_dashboard = (
+# flow_func(this.perform_dashboard_testing)
+# .Next(this.deploy_dashboard)
+# )
+#
+# deploy_dashboard = (
+# flow_func(this.deploy_dashboard_to_production)
+# .Next(this.complete_management)
+# )
+#
+# complete_management = (
+# flow_func(this.finalize_dashboard_management)
+# .Next(this.end)
+# )
+#
+# end = flow_func(this.end_dashboard_management)
+#
+# # Flow functions
+# def start_dashboard_management(self, activation):
+# """Initialize the dashboard management process"""
+# process = activation.process
+# dashboard = process.dashboard
+#
+# # Send dashboard creation notification
+# self.notify_dashboard_creation(dashboard)
+#
+# def setup_dashboard_widgets(self, activation):
+# """Setup dashboard widgets"""
+# process = activation.process
+# dashboard = process.dashboard
+#
+# # Create default widgets based on dashboard type
+# self.create_default_widgets(dashboard)
+#
+# # Mark widgets created
+# process.widgets_created = True
+# process.save()
+#
+# def setup_dashboard_layout(self, activation):
+# """Setup dashboard layout"""
+# process = activation.process
+# dashboard = process.dashboard
+#
+# # Configure dashboard layout
+# self.configure_layout_settings(dashboard)
+#
+# # Mark layout configured
+# process.layout_configured = True
+# process.save()
+#
+# def configure_dashboard_permissions(self, activation):
+# """Configure dashboard permissions"""
+# process = activation.process
+# dashboard = process.dashboard
+#
+# # Set up access permissions
+# self.setup_access_permissions(dashboard)
+#
+# # Mark permissions set
+# process.permissions_set = True
+# process.save()
+#
+# def perform_dashboard_testing(self, activation):
+# """Perform dashboard testing"""
+# process = activation.process
+# dashboard = process.dashboard
+#
+# # Test dashboard functionality
+# test_results = self.test_dashboard_functionality(dashboard)
+#
+# # Mark dashboard tested
+# process.dashboard_tested = True
+# process.save()
+#
+# # Store test results
+# self.store_test_results(dashboard, test_results)
+#
+# def deploy_dashboard_to_production(self, activation):
+# """Deploy dashboard to production"""
+# process = activation.process
+# dashboard = process.dashboard
+#
+# # Deploy dashboard
+# self.deploy_dashboard(dashboard)
+#
+# # Mark dashboard deployed
+# process.dashboard_deployed = True
+# process.save()
+#
+# # Activate dashboard
+# dashboard.is_active = True
+# dashboard.save()
+#
+# def finalize_dashboard_management(self, activation):
+# """Finalize the dashboard management process"""
+# process = activation.process
+# dashboard = process.dashboard
+#
+# # Mark management completed
+# process.management_completed = True
+# process.save()
+#
+# # Send completion notifications
+# self.notify_dashboard_completion(dashboard)
+#
+# # Schedule dashboard refresh
+# self.schedule_dashboard_refresh(dashboard)
+#
+# def end_dashboard_management(self, activation):
+# """End the dashboard management workflow"""
+# process = activation.process
+#
+# # Generate dashboard summary
+# self.generate_dashboard_summary(process.dashboard)
+#
+# # Helper methods
+# def notify_dashboard_creation(self, dashboard):
+# """Notify dashboard creation"""
+# analytics_team = User.objects.filter(groups__name='Analytics Team')
+# for staff in analytics_team:
+# send_mail(
+# subject=f'Dashboard Creation: {dashboard.name}',
+# message=f'Dashboard creation process started for "{dashboard.name}".',
+# from_email='analytics@hospital.com',
+# recipient_list=[staff.email],
+# fail_silently=True
+# )
+#
+# def create_default_widgets(self, dashboard):
+# """Create default widgets for dashboard"""
+# # This would create default widgets based on dashboard type
+# pass
+#
+# def configure_layout_settings(self, dashboard):
+# """Configure dashboard layout settings"""
+# # This would configure layout settings
+# pass
+#
+# def setup_access_permissions(self, dashboard):
+# """Setup dashboard access permissions"""
+# # This would configure access permissions
+# pass
+#
+# def test_dashboard_functionality(self, dashboard):
+# """Test dashboard functionality"""
+# # This would test dashboard functionality
+# return {'status': 'passed', 'issues': []}
+#
+# def store_test_results(self, dashboard, results):
+# """Store dashboard test results"""
+# # This would store test results
+# pass
+#
+# def deploy_dashboard(self, dashboard):
+# """Deploy dashboard to production"""
+# # This would deploy dashboard
+# pass
+#
+# def notify_dashboard_completion(self, dashboard):
+# """Notify dashboard completion"""
+# # Notify dashboard users
+# for user in dashboard.allowed_users.all():
+# if user.email:
+# send_mail(
+# subject=f'Dashboard Available: {dashboard.name}',
+# message=f'Dashboard "{dashboard.name}" is now available.',
+# from_email='analytics@hospital.com',
+# recipient_list=[user.email],
+# fail_silently=True
+# )
+#
+# def schedule_dashboard_refresh(self, dashboard):
+# """Schedule dashboard refresh"""
+# # Schedule dashboard refresh task
+# refresh_dashboard.apply_async(
+# args=[dashboard.dashboard_id],
+# countdown=dashboard.refresh_interval
+# )
+#
+# def generate_dashboard_summary(self, dashboard):
+# """Generate dashboard summary"""
+# # This would generate dashboard summary
+# pass
+#
+#
+# class MetricCalculationProcess(Process):
+# """
+# Viewflow process model for metric calculation
+# """
+# metric_definition = ModelField(MetricDefinition, help_text='Associated metric definition')
+#
+# # Process status tracking
+# calculation_triggered = models.BooleanField(default=False)
+# data_collected = models.BooleanField(default=False)
+# metrics_calculated = models.BooleanField(default=False)
+# quality_validated = models.BooleanField(default=False)
+# thresholds_checked = models.BooleanField(default=False)
+# alerts_sent = models.BooleanField(default=False)
+# calculation_completed = models.BooleanField(default=False)
+#
+# class Meta:
+# verbose_name = 'Metric Calculation Process'
+# verbose_name_plural = 'Metric Calculation Processes'
+#
+#
+# class MetricCalculationFlow(Flow):
+# """
+# Metric Calculation Workflow
+#
+# This flow manages automated metric calculation including
+# data collection, calculation, validation, and alerting.
+# """
+#
+# process_class = MetricCalculationProcess
+#
+# # Flow definition
+# start = (
+# flow_func(this.start_metric_calculation)
+# .Next(this.trigger_calculation)
+# )
+#
+# trigger_calculation = (
+# flow_func(this.initiate_calculation)
+# .Next(this.collect_data)
+# )
+#
+# collect_data = (
+# flow_func(this.gather_metric_data)
+# .Next(this.calculate_metrics)
+# )
+#
+# calculate_metrics = (
+# flow_view(MetricCalculationView)
+# .Permission('analytics.can_calculate_metrics')
+# .Next(this.validate_quality)
+# )
+#
+# validate_quality = (
+# flow_func(this.perform_quality_validation)
+# .Next(this.check_thresholds)
+# )
+#
+# check_thresholds = (
+# flow_func(this.evaluate_thresholds)
+# .Next(this.send_alerts)
+# )
+#
+# send_alerts = (
+# flow_func(this.dispatch_threshold_alerts)
+# .Next(this.complete_calculation)
+# )
+#
+# complete_calculation = (
+# flow_func(this.finalize_metric_calculation)
+# .Next(this.end)
+# )
+#
+# end = flow_func(this.end_metric_calculation)
+#
+# # Flow functions
+# def start_metric_calculation(self, activation):
+# """Initialize the metric calculation process"""
+# process = activation.process
+# metric = process.metric_definition
+#
+# # Send calculation notification
+# self.notify_calculation_start(metric)
+#
+# def initiate_calculation(self, activation):
+# """Initiate metric calculation"""
+# process = activation.process
+# metric = process.metric_definition
+#
+# # Mark calculation triggered
+# process.calculation_triggered = True
+# process.save()
+#
+# # Prepare calculation environment
+# self.prepare_calculation_environment(metric)
+#
+# def gather_metric_data(self, activation):
+# """Gather data for metric calculation"""
+# process = activation.process
+# metric = process.metric_definition
+#
+# # Collect data from configured sources
+# collected_data = self.collect_calculation_data(metric)
+#
+# # Mark data collected
+# process.data_collected = True
+# process.save()
+#
+# # Store collected data
+# self.store_calculation_data(metric, collected_data)
+#
+# def perform_quality_validation(self, activation):
+# """Perform data quality validation"""
+# process = activation.process
+# metric = process.metric_definition
+#
+# # Validate data quality
+# quality_results = self.validate_data_quality(metric)
+#
+# # Mark quality validated
+# process.quality_validated = True
+# process.save()
+#
+# # Store quality results
+# self.store_quality_results(metric, quality_results)
+#
+# def evaluate_thresholds(self, activation):
+# """Evaluate metric thresholds"""
+# process = activation.process
+# metric = process.metric_definition
+#
+# # Check threshold violations
+# threshold_results = self.check_metric_thresholds(metric)
+#
+# # Mark thresholds checked
+# process.thresholds_checked = True
+# process.save()
+#
+# # Store threshold results
+# self.store_threshold_results(metric, threshold_results)
+#
+# def dispatch_threshold_alerts(self, activation):
+# """Dispatch threshold alerts"""
+# process = activation.process
+# metric = process.metric_definition
+#
+# # Send threshold alerts if needed
+# self.send_threshold_alerts(metric)
+#
+# # Mark alerts sent
+# process.alerts_sent = True
+# process.save()
+#
+# def finalize_metric_calculation(self, activation):
+# """Finalize the metric calculation process"""
+# process = activation.process
+# metric = process.metric_definition
+#
+# # Mark calculation completed
+# process.calculation_completed = True
+# process.save()
+#
+# # Send completion notifications
+# self.notify_calculation_completion(metric)
+#
+# # Schedule next calculation
+# self.schedule_next_calculation(metric)
+#
+# def end_metric_calculation(self, activation):
+# """End the metric calculation workflow"""
+# process = activation.process
+#
+# # Generate calculation summary
+# self.generate_calculation_summary(process.metric_definition)
+#
+# # Helper methods
+# def notify_calculation_start(self, metric):
+# """Notify metric calculation start"""
+# # This would notify relevant parties
+# pass
+#
+# def prepare_calculation_environment(self, metric):
+# """Prepare calculation environment"""
+# # This would prepare calculation environment
+# pass
+#
+# def collect_calculation_data(self, metric):
+# """Collect data for calculation"""
+# # This would collect data from configured sources
+# return {'status': 'collected', 'records': 1000}
+#
+# def store_calculation_data(self, metric, data):
+# """Store calculation data"""
+# # This would store calculation data
+# pass
+#
+# def validate_data_quality(self, metric):
+# """Validate data quality"""
+# # This would validate data quality
+# return {'quality_score': 95, 'issues': []}
+#
+# def store_quality_results(self, metric, results):
+# """Store quality validation results"""
+# # This would store quality results
+# pass
+#
+# def check_metric_thresholds(self, metric):
+# """Check metric thresholds"""
+# # This would check threshold violations
+# return {'violations': [], 'status': 'normal'}
+#
+# def store_threshold_results(self, metric, results):
+# """Store threshold check results"""
+# # This would store threshold results
+# pass
+#
+# def send_threshold_alerts(self, metric):
+# """Send threshold violation alerts"""
+# # This would send alerts for threshold violations
+# pass
+#
+# def notify_calculation_completion(self, metric):
+# """Notify calculation completion"""
+# # This would notify completion
+# pass
+#
+# def schedule_next_calculation(self, metric):
+# """Schedule next metric calculation"""
+# # Schedule next calculation based on aggregation period
+# if metric.aggregation_period == 'HOURLY':
+# countdown = 3600
+# elif metric.aggregation_period == 'DAILY':
+# countdown = 86400
+# else:
+# countdown = 3600 # Default to hourly
+#
+# calculate_metric.apply_async(
+# args=[metric.metric_id],
+# countdown=countdown
+# )
+#
+# def generate_calculation_summary(self, metric):
+# """Generate calculation summary"""
+# # This would generate calculation summary
+# pass
+#
+#
+# # Celery tasks for background processing
+# @celery.job
+# def schedule_report_execution(report_id):
+# """Background task to schedule report execution"""
+# try:
+# report = Report.objects.get(report_id=report_id)
+#
+# # Create report execution
+# execution = ReportExecution.objects.create(
+# report=report,
+# execution_type='SCHEDULED',
+# status='PENDING'
+# )
+#
+# # Start report generation workflow
+# # This would start the report generation workflow
+#
+# return True
+# except Exception:
+# return False
+#
+#
+# @celery.job
+# def refresh_dashboard(dashboard_id):
+# """Background task to refresh dashboard data"""
+# try:
+# dashboard = Dashboard.objects.get(dashboard_id=dashboard_id)
+#
+# # Refresh all dashboard widgets
+# for widget in dashboard.widgets.all():
+# refresh_widget_data(widget)
+#
+# # Schedule next refresh
+# refresh_dashboard.apply_async(
+# args=[dashboard_id],
+# countdown=dashboard.refresh_interval
+# )
+#
+# return True
+# except Exception:
+# return False
+#
+#
+# @celery.job
+# def calculate_metric(metric_id):
+# """Background task to calculate metric values"""
+# try:
+# metric = MetricDefinition.objects.get(metric_id=metric_id)
+#
+# # Start metric calculation workflow
+# # This would start the metric calculation workflow
+#
+# return True
+# except Exception:
+# return False
+#
+#
+# @celery.job
+# def cleanup_old_reports():
+# """Background task to cleanup old report files"""
+# try:
+# # This would cleanup old report files
+# return True
+# except Exception:
+# return False
+#
+#
+# @celery.job
+# def generate_analytics_summary():
+# """Background task to generate analytics summary"""
+# try:
+# # This would generate periodic analytics summary
+# return True
+# except Exception:
+# return False
+#
+#
+# def refresh_widget_data(widget):
+# """Helper function to refresh widget data"""
+# # This would refresh widget data
+# pass
+#
diff --git a/analytics/forms.py b/analytics/forms.py
index f4b71d15..e4ca6158 100644
--- a/analytics/forms.py
+++ b/analytics/forms.py
@@ -396,3 +396,724 @@ class MetricDefinitionForm(forms.ModelForm):
return cleaned_data
+
+# from django import forms
+# from django.core.exceptions import ValidationError
+# from django.utils import timezone
+# from crispy_forms.helper import FormHelper
+# from crispy_forms.layout import Layout, Fieldset, Submit, Row, Column, HTML, Div
+# from crispy_forms.bootstrap import FormActions
+# import json
+#
+# from .models import Dashboard, DashboardWidget, DataSource, Report, MetricDefinition
+# from core.models import Tenant
+#
+#
+# class ReportGenerationForm(forms.ModelForm):
+# """
+# Form for report generation configuration
+# """
+# parameters = forms.CharField(
+# required=False,
+# widget=forms.Textarea(attrs={'class': 'form-control', 'rows': 4})
+# )
+# output_format = forms.ChoiceField(
+# choices=[
+# ('pdf', 'PDF'),
+# ('excel', 'Excel'),
+# ('csv', 'CSV'),
+# ('json', 'JSON')
+# ],
+# required=True,
+# widget=forms.Select(attrs={'class': 'form-control'})
+# )
+# schedule_execution = forms.BooleanField(
+# required=False,
+# widget=forms.CheckboxInput(attrs={'class': 'form-check-input'})
+# )
+# execution_time = forms.DateTimeField(
+# required=False,
+# widget=forms.DateTimeInput(attrs={'class': 'form-control', 'type': 'datetime-local'})
+# )
+# email_recipients = forms.CharField(
+# required=False,
+# widget=forms.Textarea(attrs={'class': 'form-control', 'rows': 3})
+# )
+#
+# class Meta:
+# model = Report
+# fields = [
+# 'name', 'description', 'report_type', 'data_sources',
+# 'parameters', 'output_format', 'schedule_execution',
+# 'execution_time', 'email_recipients'
+# ]
+# widgets = {
+# 'name': forms.TextInput(attrs={'class': 'form-control'}),
+# 'description': forms.Textarea(attrs={'class': 'form-control', 'rows': 3}),
+# 'report_type': forms.Select(attrs={'class': 'form-control'}),
+# 'data_sources': forms.CheckboxSelectMultiple(attrs={'class': 'form-check-input'})
+# }
+#
+# def __init__(self, *args, **kwargs):
+# tenant = kwargs.pop('tenant', None)
+# super().__init__(*args, **kwargs)
+#
+# if tenant:
+# self.fields['data_sources'].queryset = DataSource.objects.filter(tenant=tenant)
+#
+# self.helper = FormHelper()
+# self.helper.layout = Layout(
+# Fieldset(
+# 'Report Configuration',
+# Row(
+# Column('name', css_class='form-group col-md-6 mb-0'),
+# Column('report_type', css_class='form-group col-md-6 mb-0'),
+# css_class='form-row'
+# ),
+# 'description',
+# 'data_sources',
+# 'parameters'
+# ),
+# Fieldset(
+# 'Output Settings',
+# Row(
+# Column('output_format', css_class='form-group col-md-6 mb-0'),
+# Column('email_recipients', css_class='form-group col-md-6 mb-0'),
+# css_class='form-row'
+# )
+# ),
+# Fieldset(
+# 'Scheduling',
+# HTML(''),
+# 'schedule_execution',
+# HTML(
+# ''),
+# HTML('
'),
+# 'execution_time'
+# ),
+# FormActions(
+# Submit('submit', 'Generate Report', css_class='btn btn-primary'),
+# HTML('Cancel')
+# )
+# )
+#
+# def clean_parameters(self):
+# parameters = self.cleaned_data.get('parameters')
+# if parameters:
+# try:
+# json.loads(parameters)
+# except json.JSONDecodeError:
+# raise ValidationError('Parameters must be valid JSON.')
+# return parameters
+#
+# def clean(self):
+# cleaned_data = super().clean()
+# schedule_execution = cleaned_data.get('schedule_execution')
+# execution_time = cleaned_data.get('execution_time')
+#
+# if schedule_execution and not execution_time:
+# raise ValidationError('Execution time is required when scheduling execution.')
+#
+# return cleaned_data
+#
+#
+# class DashboardCreationForm(forms.ModelForm):
+# """
+# Form for dashboard creation
+# """
+# layout_template = forms.ChoiceField(
+# choices=[
+# ('grid_2x2', '2x2 Grid'),
+# ('grid_3x3', '3x3 Grid'),
+# ('sidebar_main', 'Sidebar + Main'),
+# ('top_bottom', 'Top + Bottom'),
+# ('custom', 'Custom Layout')
+# ],
+# required=True,
+# widget=forms.Select(attrs={'class': 'form-control'})
+# )
+# copy_from_dashboard = forms.ModelChoiceField(
+# queryset=None,
+# required=False,
+# widget=forms.Select(attrs={'class': 'form-control'})
+# )
+#
+# class Meta:
+# model = Dashboard
+# fields = [
+# 'name', 'description', 'dashboard_type', 'layout_template',
+# 'refresh_interval', 'is_public', 'allowed_roles',
+# 'copy_from_dashboard'
+# ]
+# widgets = {
+# 'name': forms.TextInput(attrs={'class': 'form-control'}),
+# 'description': forms.Textarea(attrs={'class': 'form-control', 'rows': 3}),
+# 'dashboard_type': forms.Select(attrs={'class': 'form-control'}),
+# 'refresh_interval': forms.NumberInput(attrs={'class': 'form-control'}),
+# 'is_public': forms.CheckboxInput(attrs={'class': 'form-check-input'}),
+# 'allowed_roles': forms.Textarea(attrs={'class': 'form-control', 'rows': 2})
+# }
+#
+# def __init__(self, *args, **kwargs):
+# tenant = kwargs.pop('tenant', None)
+# super().__init__(*args, **kwargs)
+#
+# if tenant:
+# self.fields['copy_from_dashboard'].queryset = Dashboard.objects.filter(
+# tenant=tenant,
+# is_active=True
+# )
+#
+# self.helper = FormHelper()
+# self.helper.layout = Layout(
+# Fieldset(
+# 'Dashboard Information',
+# Row(
+# Column('name', css_class='form-group col-md-6 mb-0'),
+# Column('dashboard_type', css_class='form-group col-md-6 mb-0'),
+# css_class='form-row'
+# ),
+# 'description'
+# ),
+# Fieldset(
+# 'Layout Configuration',
+# Row(
+# Column('layout_template', css_class='form-group col-md-6 mb-0'),
+# Column('refresh_interval', css_class='form-group col-md-6 mb-0'),
+# css_class='form-row'
+# ),
+# 'copy_from_dashboard'
+# ),
+# Fieldset(
+# 'Access Control',
+# HTML(''),
+# 'is_public',
+# HTML(''),
+# HTML('
'),
+# 'allowed_roles'
+# ),
+# FormActions(
+# Submit('submit', 'Create Dashboard', css_class='btn btn-primary'),
+# HTML('Cancel')
+# )
+# )
+#
+#
+# class DataSourceConfigurationForm(forms.ModelForm):
+# """
+# Form for data source configuration
+# """
+# test_connection = forms.BooleanField(
+# required=False,
+# initial=True,
+# widget=forms.CheckboxInput(attrs={'class': 'form-check-input'})
+# )
+#
+# class Meta:
+# model = DataSource
+# fields = [
+# 'name', 'description', 'source_type', 'connection_config',
+# 'query_config', 'refresh_interval', 'is_active',
+# 'test_connection'
+# ]
+# widgets = {
+# 'name': forms.TextInput(attrs={'class': 'form-control'}),
+# 'description': forms.Textarea(attrs={'class': 'form-control', 'rows': 3}),
+# 'source_type': forms.Select(attrs={'class': 'form-control'}),
+# 'connection_config': forms.Textarea(attrs={'class': 'form-control', 'rows': 5}),
+# 'query_config': forms.Textarea(attrs={'class': 'form-control', 'rows': 5}),
+# 'refresh_interval': forms.NumberInput(attrs={'class': 'form-control'}),
+# 'is_active': forms.CheckboxInput(attrs={'class': 'form-check-input'})
+# }
+#
+# def __init__(self, *args, **kwargs):
+# super().__init__(*args, **kwargs)
+#
+# self.helper = FormHelper()
+# self.helper.layout = Layout(
+# Fieldset(
+# 'Data Source Information',
+# Row(
+# Column('name', css_class='form-group col-md-6 mb-0'),
+# Column('source_type', css_class='form-group col-md-6 mb-0'),
+# css_class='form-row'
+# ),
+# 'description'
+# ),
+# Fieldset(
+# 'Connection Configuration',
+# 'connection_config',
+# HTML('Enter connection details in JSON format')
+# ),
+# Fieldset(
+# 'Query Configuration',
+# 'query_config',
+# HTML('Enter query configuration in JSON format')
+# ),
+# Fieldset(
+# 'Settings',
+# Row(
+# Column('refresh_interval', css_class='form-group col-md-6 mb-0'),
+# css_class='form-row'
+# ),
+# HTML(''),
+# 'is_active',
+# HTML(''),
+# HTML('
'),
+# HTML(''),
+# 'test_connection',
+# HTML(''),
+# HTML('
')
+# ),
+# FormActions(
+# Submit('submit', 'Save Data Source', css_class='btn btn-primary'),
+# HTML('Cancel')
+# )
+# )
+#
+# def clean_connection_config(self):
+# config = self.cleaned_data.get('connection_config')
+# if config:
+# try:
+# json.loads(config)
+# except json.JSONDecodeError:
+# raise ValidationError('Connection configuration must be valid JSON.')
+# return config
+#
+# def clean_query_config(self):
+# config = self.cleaned_data.get('query_config')
+# if config:
+# try:
+# json.loads(config)
+# except json.JSONDecodeError:
+# raise ValidationError('Query configuration must be valid JSON.')
+# return config
+#
+#
+# class MetricCalculationForm(forms.ModelForm):
+# """
+# Form for metric calculation configuration
+# """
+# calculate_now = forms.BooleanField(
+# required=False,
+# widget=forms.CheckboxInput(attrs={'class': 'form-check-input'})
+# )
+# date_range_start = forms.DateField(
+# required=False,
+# widget=forms.DateInput(attrs={'class': 'form-control', 'type': 'date'})
+# )
+# date_range_end = forms.DateField(
+# required=False,
+# widget=forms.DateInput(attrs={'class': 'form-control', 'type': 'date'})
+# )
+#
+# class Meta:
+# model = MetricDefinition
+# fields = [
+# 'name', 'description', 'metric_type', 'data_source',
+# 'calculation_config', 'aggregation_period', 'target_value',
+# 'warning_threshold', 'critical_threshold', 'unit_of_measure',
+# 'calculate_now', 'date_range_start', 'date_range_end'
+# ]
+# widgets = {
+# 'name': forms.TextInput(attrs={'class': 'form-control'}),
+# 'description': forms.Textarea(attrs={'class': 'form-control', 'rows': 3}),
+# 'metric_type': forms.Select(attrs={'class': 'form-control'}),
+# 'data_source': forms.Select(attrs={'class': 'form-control'}),
+# 'calculation_config': forms.Textarea(attrs={'class': 'form-control', 'rows': 4}),
+# 'aggregation_period': forms.Select(attrs={'class': 'form-control'}),
+# 'target_value': forms.NumberInput(attrs={'class': 'form-control'}),
+# 'warning_threshold': forms.NumberInput(attrs={'class': 'form-control'}),
+# 'critical_threshold': forms.NumberInput(attrs={'class': 'form-control'}),
+# 'unit_of_measure': forms.TextInput(attrs={'class': 'form-control'})
+# }
+#
+# def __init__(self, *args, **kwargs):
+# tenant = kwargs.pop('tenant', None)
+# super().__init__(*args, **kwargs)
+#
+# if tenant:
+# self.fields['data_source'].queryset = DataSource.objects.filter(tenant=tenant)
+#
+# self.helper = FormHelper()
+# self.helper.layout = Layout(
+# Fieldset(
+# 'Metric Definition',
+# Row(
+# Column('name', css_class='form-group col-md-6 mb-0'),
+# Column('metric_type', css_class='form-group col-md-6 mb-0'),
+# css_class='form-row'
+# ),
+# 'description',
+# Row(
+# Column('data_source', css_class='form-group col-md-6 mb-0'),
+# Column('aggregation_period', css_class='form-group col-md-6 mb-0'),
+# css_class='form-row'
+# ),
+# 'calculation_config'
+# ),
+# Fieldset(
+# 'Thresholds and Targets',
+# Row(
+# Column('target_value', css_class='form-group col-md-4 mb-0'),
+# Column('warning_threshold', css_class='form-group col-md-4 mb-0'),
+# Column('critical_threshold', css_class='form-group col-md-4 mb-0'),
+# css_class='form-row'
+# ),
+# 'unit_of_measure'
+# ),
+# Fieldset(
+# 'Calculation Options',
+# HTML(''),
+# 'calculate_now',
+# HTML(''),
+# HTML('
'),
+# Row(
+# Column('date_range_start', css_class='form-group col-md-6 mb-0'),
+# Column('date_range_end', css_class='form-group col-md-6 mb-0'),
+# css_class='form-row'
+# )
+# ),
+# FormActions(
+# Submit('submit', 'Save Metric', css_class='btn btn-primary'),
+# HTML('Cancel')
+# )
+# )
+#
+# def clean_calculation_config(self):
+# config = self.cleaned_data.get('calculation_config')
+# if config:
+# try:
+# json.loads(config)
+# except json.JSONDecodeError:
+# raise ValidationError('Calculation configuration must be valid JSON.')
+# return config
+#
+#
+# class QualityAssuranceForm(forms.Form):
+# """
+# Form for quality assurance configuration
+# """
+# check_data_accuracy = forms.BooleanField(
+# required=False,
+# initial=True,
+# widget=forms.CheckboxInput(attrs={'class': 'form-check-input'})
+# )
+# validate_calculations = forms.BooleanField(
+# required=False,
+# initial=True,
+# widget=forms.CheckboxInput(attrs={'class': 'form-check-input'})
+# )
+# verify_data_sources = forms.BooleanField(
+# required=False,
+# initial=True,
+# widget=forms.CheckboxInput(attrs={'class': 'form-check-input'})
+# )
+# check_performance = forms.BooleanField(
+# required=False,
+# initial=True,
+# widget=forms.CheckboxInput(attrs={'class': 'form-check-input'})
+# )
+# generate_qa_report = forms.BooleanField(
+# required=False,
+# initial=True,
+# widget=forms.CheckboxInput(attrs={'class': 'form-check-input'})
+# )
+# qa_threshold = forms.DecimalField(
+# max_digits=5,
+# decimal_places=2,
+# initial=95.0,
+# widget=forms.NumberInput(attrs={'class': 'form-control'})
+# )
+#
+# def __init__(self, *args, **kwargs):
+# super().__init__(*args, **kwargs)
+#
+# self.helper = FormHelper()
+# self.helper.layout = Layout(
+# Fieldset(
+# 'Quality Assurance Checks',
+# HTML(''),
+# 'check_data_accuracy',
+# HTML(''),
+# HTML('
'),
+# HTML(''),
+# 'validate_calculations',
+# HTML(''),
+# HTML('
'),
+# HTML(''),
+# 'verify_data_sources',
+# HTML(''),
+# HTML('
'),
+# HTML(''),
+# 'check_performance',
+# HTML(''),
+# HTML('
'),
+# HTML(''),
+# 'generate_qa_report',
+# HTML(''),
+# HTML('
')
+# ),
+# Fieldset(
+# 'Quality Threshold',
+# 'qa_threshold',
+# HTML('Minimum quality score percentage (0-100)')
+# ),
+# FormActions(
+# Submit('submit', 'Start Quality Check', css_class='btn btn-primary'),
+# HTML('Cancel')
+# )
+# )
+#
+#
+# class DistributionForm(forms.Form):
+# """
+# Form for report distribution configuration
+# """
+# distribution_method = forms.ChoiceField(
+# choices=[
+# ('email', 'Email'),
+# ('download', 'Download Link'),
+# ('ftp', 'FTP Upload'),
+# ('api', 'API Endpoint'),
+# ('dashboard', 'Dashboard Publication')
+# ],
+# required=True,
+# widget=forms.Select(attrs={'class': 'form-control'})
+# )
+# recipients = forms.CharField(
+# required=False,
+# widget=forms.Textarea(attrs={'class': 'form-control', 'rows': 4})
+# )
+# subject = forms.CharField(
+# required=False,
+# widget=forms.TextInput(attrs={'class': 'form-control'})
+# )
+# message = forms.CharField(
+# required=False,
+# widget=forms.Textarea(attrs={'class': 'form-control', 'rows': 4})
+# )
+# schedule_distribution = forms.BooleanField(
+# required=False,
+# widget=forms.CheckboxInput(attrs={'class': 'form-check-input'})
+# )
+# distribution_time = forms.DateTimeField(
+# required=False,
+# widget=forms.DateTimeInput(attrs={'class': 'form-control', 'type': 'datetime-local'})
+# )
+#
+# def __init__(self, *args, **kwargs):
+# super().__init__(*args, **kwargs)
+#
+# self.helper = FormHelper()
+# self.helper.layout = Layout(
+# Fieldset(
+# 'Distribution Method',
+# 'distribution_method',
+# 'recipients',
+# HTML('Enter email addresses separated by commas')
+# ),
+# Fieldset(
+# 'Message Content',
+# 'subject',
+# 'message'
+# ),
+# Fieldset(
+# 'Scheduling',
+# HTML(''),
+# 'schedule_distribution',
+# HTML(''),
+# HTML('
'),
+# 'distribution_time'
+# ),
+# FormActions(
+# Submit('submit', 'Distribute Report', css_class='btn btn-primary'),
+# HTML('Cancel')
+# )
+# )
+#
+# def clean(self):
+# cleaned_data = super().clean()
+# distribution_method = cleaned_data.get('distribution_method')
+# recipients = cleaned_data.get('recipients')
+# schedule_distribution = cleaned_data.get('schedule_distribution')
+# distribution_time = cleaned_data.get('distribution_time')
+#
+# if distribution_method == 'email' and not recipients:
+# raise ValidationError('Recipients are required for email distribution.')
+#
+# if schedule_distribution and not distribution_time:
+# raise ValidationError('Distribution time is required when scheduling distribution.')
+#
+# return cleaned_data
+#
+#
+# class VisualizationForm(forms.Form):
+# """
+# Form for visualization configuration
+# """
+# chart_type = forms.ChoiceField(
+# choices=[
+# ('line', 'Line Chart'),
+# ('bar', 'Bar Chart'),
+# ('pie', 'Pie Chart'),
+# ('scatter', 'Scatter Plot'),
+# ('heatmap', 'Heat Map'),
+# ('gauge', 'Gauge'),
+# ('table', 'Data Table')
+# ],
+# required=True,
+# widget=forms.Select(attrs={'class': 'form-control'})
+# )
+# title = forms.CharField(
+# required=True,
+# widget=forms.TextInput(attrs={'class': 'form-control'})
+# )
+# x_axis_label = forms.CharField(
+# required=False,
+# widget=forms.TextInput(attrs={'class': 'form-control'})
+# )
+# y_axis_label = forms.CharField(
+# required=False,
+# widget=forms.TextInput(attrs={'class': 'form-control'})
+# )
+# color_scheme = forms.ChoiceField(
+# choices=[
+# ('default', 'Default'),
+# ('blue', 'Blue Theme'),
+# ('green', 'Green Theme'),
+# ('red', 'Red Theme'),
+# ('purple', 'Purple Theme'),
+# ('custom', 'Custom Colors')
+# ],
+# required=True,
+# widget=forms.Select(attrs={'class': 'form-control'})
+# )
+# show_legend = forms.BooleanField(
+# required=False,
+# initial=True,
+# widget=forms.CheckboxInput(attrs={'class': 'form-check-input'})
+# )
+# show_grid = forms.BooleanField(
+# required=False,
+# initial=True,
+# widget=forms.CheckboxInput(attrs={'class': 'form-check-input'})
+# )
+#
+# def __init__(self, *args, **kwargs):
+# super().__init__(*args, **kwargs)
+#
+# self.helper = FormHelper()
+# self.helper.layout = Layout(
+# Fieldset(
+# 'Chart Configuration',
+# Row(
+# Column('chart_type', css_class='form-group col-md-6 mb-0'),
+# Column('color_scheme', css_class='form-group col-md-6 mb-0'),
+# css_class='form-row'
+# ),
+# 'title'
+# ),
+# Fieldset(
+# 'Axis Labels',
+# Row(
+# Column('x_axis_label', css_class='form-group col-md-6 mb-0'),
+# Column('y_axis_label', css_class='form-group col-md-6 mb-0'),
+# css_class='form-row'
+# )
+# ),
+# Fieldset(
+# 'Display Options',
+# HTML(''),
+# 'show_legend',
+# HTML(''),
+# HTML('
'),
+# HTML(''),
+# 'show_grid',
+# HTML(''),
+# HTML('
')
+# ),
+# FormActions(
+# Submit('submit', 'Create Visualization', css_class='btn btn-primary'),
+# HTML('Cancel')
+# )
+# )
+#
+#
+# class AnalysisForm(forms.Form):
+# """
+# Form for data analysis configuration
+# """
+# analysis_type = forms.ChoiceField(
+# choices=[
+# ('descriptive', 'Descriptive Analysis'),
+# ('trend', 'Trend Analysis'),
+# ('correlation', 'Correlation Analysis'),
+# ('regression', 'Regression Analysis'),
+# ('forecasting', 'Forecasting'),
+# ('anomaly', 'Anomaly Detection')
+# ],
+# required=True,
+# widget=forms.Select(attrs={'class': 'form-control'})
+# )
+# data_source = forms.ModelChoiceField(
+# queryset=None,
+# required=True,
+# widget=forms.Select(attrs={'class': 'form-control'})
+# )
+# date_range_start = forms.DateField(
+# required=True,
+# widget=forms.DateInput(attrs={'class': 'form-control', 'type': 'date'})
+# )
+# date_range_end = forms.DateField(
+# required=True,
+# widget=forms.DateInput(attrs={'class': 'form-control', 'type': 'date'})
+# )
+# confidence_level = forms.DecimalField(
+# max_digits=5,
+# decimal_places=2,
+# initial=95.0,
+# widget=forms.NumberInput(attrs={'class': 'form-control'})
+# )
+# generate_insights = forms.BooleanField(
+# required=False,
+# initial=True,
+# widget=forms.CheckboxInput(attrs={'class': 'form-check-input'})
+# )
+#
+# def __init__(self, *args, **kwargs):
+# tenant = kwargs.pop('tenant', None)
+# super().__init__(*args, **kwargs)
+#
+# if tenant:
+# self.fields['data_source'].queryset = DataSource.objects.filter(tenant=tenant)
+#
+# self.helper = FormHelper()
+# self.helper.layout = Layout(
+# Fieldset(
+# 'Analysis Configuration',
+# Row(
+# Column('analysis_type', css_class='form-group col-md-6 mb-0'),
+# Column('data_source', css_class='form-group col-md-6 mb-0'),
+# css_class='form-row'
+# ),
+# Row(
+# Column('date_range_start', css_class='form-group col-md-6 mb-0'),
+# Column('date_range_end', css_class='form-group col-md-6 mb-0'),
+# css_class='form-row'
+# ),
+# 'confidence_level'
+# ),
+# Fieldset(
+# 'Options',
+# HTML(''),
+# 'generate_insights',
+# HTML(''),
+# HTML('
')
+# ),
+# FormActions(
+# Submit('submit', 'Start Analysis', css_class='btn btn-primary'),
+# HTML('Cancel')
+# )
+# )
+#
diff --git a/analytics/views.py b/analytics/views.py
index b95327ea..9f2fa7af 100644
--- a/analytics/views.py
+++ b/analytics/views.py
@@ -3157,4 +3157,731 @@ def report_list(request):
# 'count': len(results)
# }
#
-# return render(request, 'analytics/partials/search_results.html', context)
\ No newline at end of file
+# return render(request, 'analytics/partials/search_results.html', context)
+
+
+# from django.shortcuts import render, redirect, get_object_or_404
+# from django.contrib.auth.decorators import login_required, permission_required
+# from django.contrib.auth.mixins import LoginRequiredMixin, PermissionRequiredMixin
+# from django.contrib import messages
+# from django.views.generic import (
+# CreateView, UpdateView, DeleteView, DetailView, ListView, FormView
+# )
+# from django.urls import reverse_lazy, reverse
+# from django.http import JsonResponse, HttpResponse
+# from django.utils import timezone
+# from django.db import transaction
+# from django.core.mail import send_mail
+# from django.conf import settings
+# from viewflow.views import CreateProcessView, UpdateProcessView
+# import json
+#
+# from .models import Dashboard, DashboardWidget, DataSource, Report, MetricDefinition, ReportExecution
+# from .forms import (
+# ReportGenerationForm, DashboardCreationForm, DataSourceConfigurationForm,
+# MetricCalculationForm, QualityAssuranceForm, DistributionForm,
+# VisualizationForm, AnalysisForm
+# )
+# from .flows import ReportGenerationFlow, DashboardManagementFlow, MetricCalculationFlow
+#
+#
+# class ReportGenerationView(LoginRequiredMixin, PermissionRequiredMixin, CreateProcessView):
+# """
+# View for report generation workflow
+# """
+# model = Report
+# form_class = ReportGenerationForm
+# template_name = 'analytics/report_generation.html'
+# permission_required = 'analytics.can_generate_reports'
+# flow_class = ReportGenerationFlow
+#
+# def get_form_kwargs(self):
+# kwargs = super().get_form_kwargs()
+# kwargs['tenant'] = self.request.user.tenant
+# return kwargs
+#
+# def form_valid(self, form):
+# with transaction.atomic():
+# # Create report
+# report = form.save(commit=False)
+# report.tenant = self.request.user.tenant
+# report.created_by = self.request.user
+# report.save()
+#
+# # Save many-to-many relationships
+# form.save_m2m()
+#
+# # Start report generation workflow
+# process = self.flow_class.start.run(
+# report=report,
+# created_by=self.request.user
+# )
+#
+# messages.success(
+# self.request,
+# f'Report generation initiated for "{report.name}". '
+# f'You will be notified when the report is ready.'
+# )
+#
+# return redirect('analytics:report_detail', pk=report.pk)
+#
+# def get_context_data(self, **kwargs):
+# context = super().get_context_data(**kwargs)
+# context['title'] = 'Generate Report'
+# context['breadcrumbs'] = [
+# {'name': 'Home', 'url': reverse('core:dashboard')},
+# {'name': 'Analytics', 'url': reverse('analytics:dashboard')},
+# {'name': 'Reports', 'url': reverse('analytics:report_list')},
+# {'name': 'Generate Report', 'url': ''}
+# ]
+# return context
+#
+#
+# class DashboardCreationView(LoginRequiredMixin, PermissionRequiredMixin, CreateProcessView):
+# """
+# View for dashboard creation workflow
+# """
+# model = Dashboard
+# form_class = DashboardCreationForm
+# template_name = 'analytics/dashboard_creation.html'
+# permission_required = 'analytics.can_create_dashboards'
+# flow_class = DashboardManagementFlow
+#
+# def get_form_kwargs(self):
+# kwargs = super().get_form_kwargs()
+# kwargs['tenant'] = self.request.user.tenant
+# return kwargs
+#
+# def form_valid(self, form):
+# with transaction.atomic():
+# # Create dashboard
+# dashboard = form.save(commit=False)
+# dashboard.tenant = self.request.user.tenant
+# dashboard.created_by = self.request.user
+# dashboard.save()
+#
+# # Start dashboard creation workflow
+# process = self.flow_class.start.run(
+# dashboard=dashboard,
+# created_by=self.request.user
+# )
+#
+# messages.success(
+# self.request,
+# f'Dashboard "{dashboard.name}" created successfully. '
+# f'You can now add widgets and configure the layout.'
+# )
+#
+# return redirect('analytics:dashboard_detail', pk=dashboard.pk)
+#
+# def get_context_data(self, **kwargs):
+# context = super().get_context_data(**kwargs)
+# context['title'] = 'Create Dashboard'
+# context['breadcrumbs'] = [
+# {'name': 'Home', 'url': reverse('core:dashboard')},
+# {'name': 'Analytics', 'url': reverse('analytics:dashboard')},
+# {'name': 'Dashboards', 'url': reverse('analytics:dashboard_list')},
+# {'name': 'Create Dashboard', 'url': ''}
+# ]
+# return context
+#
+#
+# class DataSourceConfigurationView(LoginRequiredMixin, PermissionRequiredMixin, CreateView):
+# """
+# View for data source configuration
+# """
+# model = DataSource
+# form_class = DataSourceConfigurationForm
+# template_name = 'analytics/data_source_configuration.html'
+# permission_required = 'analytics.can_configure_data_sources'
+#
+# def get_success_url(self):
+# return reverse('analytics:data_source_detail', kwargs={'pk': self.object.pk})
+#
+# def form_valid(self, form):
+# data_source = form.save(commit=False)
+# data_source.tenant = self.request.user.tenant
+# data_source.created_by = self.request.user
+# data_source.save()
+#
+# # Test connection if requested
+# if form.cleaned_data.get('test_connection'):
+# connection_result = self.test_data_source_connection(data_source)
+# if connection_result['success']:
+# messages.success(
+# self.request,
+# f'Data source "{data_source.name}" configured successfully. Connection test passed.'
+# )
+# else:
+# messages.warning(
+# self.request,
+# f'Data source "{data_source.name}" configured, but connection test failed: {connection_result["error"]}'
+# )
+# else:
+# messages.success(
+# self.request,
+# f'Data source "{data_source.name}" configured successfully.'
+# )
+#
+# return super().form_valid(form)
+#
+# def test_data_source_connection(self, data_source):
+# """Test data source connection"""
+# try:
+# # Implement connection testing logic based on source type
+# if data_source.source_type == 'database':
+# return self.test_database_connection(data_source)
+# elif data_source.source_type == 'api':
+# return self.test_api_connection(data_source)
+# elif data_source.source_type == 'file':
+# return self.test_file_connection(data_source)
+# else:
+# return {'success': True}
+# except Exception as e:
+# return {'success': False, 'error': str(e)}
+#
+# def test_database_connection(self, data_source):
+# """Test database connection"""
+# # Implement database connection testing
+# return {'success': True}
+#
+# def test_api_connection(self, data_source):
+# """Test API connection"""
+# # Implement API connection testing
+# return {'success': True}
+#
+# def test_file_connection(self, data_source):
+# """Test file connection"""
+# # Implement file connection testing
+# return {'success': True}
+#
+# def get_context_data(self, **kwargs):
+# context = super().get_context_data(**kwargs)
+# context['title'] = 'Configure Data Source'
+# return context
+#
+#
+# class MetricCalculationView(LoginRequiredMixin, PermissionRequiredMixin, CreateProcessView):
+# """
+# View for metric calculation workflow
+# """
+# model = MetricDefinition
+# form_class = MetricCalculationForm
+# template_name = 'analytics/metric_calculation.html'
+# permission_required = 'analytics.can_calculate_metrics'
+# flow_class = MetricCalculationFlow
+#
+# def get_form_kwargs(self):
+# kwargs = super().get_form_kwargs()
+# kwargs['tenant'] = self.request.user.tenant
+# return kwargs
+#
+# def form_valid(self, form):
+# with transaction.atomic():
+# # Create metric definition
+# metric = form.save(commit=False)
+# metric.tenant = self.request.user.tenant
+# metric.created_by = self.request.user
+# metric.save()
+#
+# # Start metric calculation workflow
+# process = self.flow_class.start.run(
+# metric=metric,
+# calculate_now=form.cleaned_data.get('calculate_now', False),
+# date_range_start=form.cleaned_data.get('date_range_start'),
+# date_range_end=form.cleaned_data.get('date_range_end'),
+# created_by=self.request.user
+# )
+#
+# if form.cleaned_data.get('calculate_now'):
+# messages.success(
+# self.request,
+# f'Metric "{metric.name}" created and calculation initiated. '
+# f'Results will be available shortly.'
+# )
+# else:
+# messages.success(
+# self.request,
+# f'Metric "{metric.name}" created successfully.'
+# )
+#
+# return redirect('analytics:metric_detail', pk=metric.pk)
+#
+# def get_context_data(self, **kwargs):
+# context = super().get_context_data(**kwargs)
+# context['title'] = 'Calculate Metric'
+# context['breadcrumbs'] = [
+# {'name': 'Home', 'url': reverse('core:dashboard')},
+# {'name': 'Analytics', 'url': reverse('analytics:dashboard')},
+# {'name': 'Metrics', 'url': reverse('analytics:metric_list')},
+# {'name': 'Calculate Metric', 'url': ''}
+# ]
+# return context
+#
+#
+# class QualityAssuranceView(LoginRequiredMixin, PermissionRequiredMixin, FormView):
+# """
+# View for quality assurance configuration
+# """
+# form_class = QualityAssuranceForm
+# template_name = 'analytics/quality_assurance.html'
+# permission_required = 'analytics.can_perform_qa'
+#
+# def get_success_url(self):
+# return reverse('analytics:dashboard')
+#
+# def form_valid(self, form):
+# qa_config = form.cleaned_data
+#
+# # Start quality assurance process
+# self.start_quality_assurance(qa_config)
+#
+# messages.success(
+# self.request,
+# 'Quality assurance process initiated. You will receive a notification when complete.'
+# )
+#
+# return super().form_valid(form)
+#
+# def start_quality_assurance(self, config):
+# """Start quality assurance process"""
+# # This would start the QA process
+# pass
+#
+# def get_context_data(self, **kwargs):
+# context = super().get_context_data(**kwargs)
+# context['title'] = 'Quality Assurance'
+# context['qa_metrics'] = self.get_qa_metrics()
+# return context
+#
+# def get_qa_metrics(self):
+# """Get quality assurance metrics"""
+# return {
+# 'data_accuracy': 98.5,
+# 'calculation_accuracy': 99.2,
+# 'source_reliability': 97.8,
+# 'performance_score': 95.6
+# }
+#
+#
+# class DistributionView(LoginRequiredMixin, PermissionRequiredMixin, FormView):
+# """
+# View for report distribution
+# """
+# form_class = DistributionForm
+# template_name = 'analytics/distribution.html'
+# permission_required = 'analytics.can_distribute_reports'
+#
+# def get_success_url(self):
+# return reverse('analytics:report_detail', kwargs={'pk': self.kwargs['pk']})
+#
+# def form_valid(self, form):
+# report = get_object_or_404(Report, pk=self.kwargs['pk'])
+# distribution_config = form.cleaned_data
+#
+# # Start distribution process
+# self.distribute_report(report, distribution_config)
+#
+# messages.success(
+# self.request,
+# f'Report "{report.name}" distribution initiated.'
+# )
+#
+# return super().form_valid(form)
+#
+# def distribute_report(self, report, config):
+# """Distribute report based on configuration"""
+# method = config['distribution_method']
+#
+# if method == 'email':
+# self.distribute_via_email(report, config)
+# elif method == 'download':
+# self.create_download_link(report, config)
+# elif method == 'ftp':
+# self.upload_to_ftp(report, config)
+# elif method == 'api':
+# self.publish_to_api(report, config)
+# elif method == 'dashboard':
+# self.publish_to_dashboard(report, config)
+#
+# def distribute_via_email(self, report, config):
+# """Distribute report via email"""
+# recipients = [email.strip() for email in config['recipients'].split(',')]
+#
+# send_mail(
+# subject=config.get('subject', f'Report: {report.name}'),
+# message=config.get('message', f'Please find the attached report: {report.name}'),
+# from_email=settings.DEFAULT_FROM_EMAIL,
+# recipient_list=recipients,
+# fail_silently=False
+# )
+#
+# def create_download_link(self, report, config):
+# """Create download link for report"""
+# # Implement download link creation
+# pass
+#
+# def upload_to_ftp(self, report, config):
+# """Upload report to FTP server"""
+# # Implement FTP upload
+# pass
+#
+# def publish_to_api(self, report, config):
+# """Publish report to API endpoint"""
+# # Implement API publication
+# pass
+#
+# def publish_to_dashboard(self, report, config):
+# """Publish report to dashboard"""
+# # Implement dashboard publication
+# pass
+#
+# def get_context_data(self, **kwargs):
+# context = super().get_context_data(**kwargs)
+# context['report'] = get_object_or_404(Report, pk=self.kwargs['pk'])
+# context['title'] = 'Distribute Report'
+# return context
+#
+#
+# class VisualizationView(LoginRequiredMixin, PermissionRequiredMixin, FormView):
+# """
+# View for visualization configuration
+# """
+# form_class = VisualizationForm
+# template_name = 'analytics/visualization.html'
+# permission_required = 'analytics.can_create_visualizations'
+#
+# def get_success_url(self):
+# return reverse('analytics:dashboard_detail', kwargs={'pk': self.kwargs['pk']})
+#
+# def form_valid(self, form):
+# dashboard = get_object_or_404(Dashboard, pk=self.kwargs['pk'])
+# visualization_config = form.cleaned_data
+#
+# # Create visualization widget
+# widget = self.create_visualization_widget(dashboard, visualization_config)
+#
+# messages.success(
+# self.request,
+# f'Visualization "{visualization_config["title"]}" added to dashboard.'
+# )
+#
+# return super().form_valid(form)
+#
+# def create_visualization_widget(self, dashboard, config):
+# """Create visualization widget"""
+# widget = DashboardWidget.objects.create(
+# dashboard=dashboard,
+# widget_type='chart',
+# title=config['title'],
+# configuration=config,
+# position_x=0,
+# position_y=0,
+# width=6,
+# height=4,
+# created_by=self.request.user
+# )
+# return widget
+#
+# def get_context_data(self, **kwargs):
+# context = super().get_context_data(**kwargs)
+# context['dashboard'] = get_object_or_404(Dashboard, pk=self.kwargs['pk'])
+# context['title'] = 'Create Visualization'
+# return context
+#
+#
+# class AnalysisView(LoginRequiredMixin, PermissionRequiredMixin, FormView):
+# """
+# View for data analysis
+# """
+# form_class = AnalysisForm
+# template_name = 'analytics/analysis.html'
+# permission_required = 'analytics.can_perform_analysis'
+#
+# def get_success_url(self):
+# return reverse('analytics:dashboard')
+#
+# def get_form_kwargs(self):
+# kwargs = super().get_form_kwargs()
+# kwargs['tenant'] = self.request.user.tenant
+# return kwargs
+#
+# def form_valid(self, form):
+# analysis_config = form.cleaned_data
+#
+# # Start analysis process
+# analysis_result = self.perform_analysis(analysis_config)
+#
+# messages.success(
+# self.request,
+# 'Data analysis completed successfully. Results are available in the dashboard.'
+# )
+#
+# return super().form_valid(form)
+#
+# def perform_analysis(self, config):
+# """Perform data analysis"""
+# analysis_type = config['analysis_type']
+#
+# if analysis_type == 'descriptive':
+# return self.descriptive_analysis(config)
+# elif analysis_type == 'trend':
+# return self.trend_analysis(config)
+# elif analysis_type == 'correlation':
+# return self.correlation_analysis(config)
+# elif analysis_type == 'regression':
+# return self.regression_analysis(config)
+# elif analysis_type == 'forecasting':
+# return self.forecasting_analysis(config)
+# elif analysis_type == 'anomaly':
+# return self.anomaly_detection(config)
+#
+# def descriptive_analysis(self, config):
+# """Perform descriptive analysis"""
+# # Implement descriptive analysis
+# return {}
+#
+# def trend_analysis(self, config):
+# """Perform trend analysis"""
+# # Implement trend analysis
+# return {}
+#
+# def correlation_analysis(self, config):
+# """Perform correlation analysis"""
+# # Implement correlation analysis
+# return {}
+#
+# def regression_analysis(self, config):
+# """Perform regression analysis"""
+# # Implement regression analysis
+# return {}
+#
+# def forecasting_analysis(self, config):
+# """Perform forecasting analysis"""
+# # Implement forecasting analysis
+# return {}
+#
+# def anomaly_detection(self, config):
+# """Perform anomaly detection"""
+# # Implement anomaly detection
+# return {}
+#
+# def get_context_data(self, **kwargs):
+# context = super().get_context_data(**kwargs)
+# context['title'] = 'Data Analysis'
+# return context
+#
+#
+# class DashboardListView(LoginRequiredMixin, PermissionRequiredMixin, ListView):
+# """
+# View for listing dashboards
+# """
+# model = Dashboard
+# template_name = 'analytics/dashboard_list.html'
+# context_object_name = 'dashboards'
+# permission_required = 'analytics.view_dashboard'
+# paginate_by = 20
+#
+# def get_queryset(self):
+# queryset = Dashboard.objects.filter(tenant=self.request.user.tenant)
+#
+# # Apply filters
+# search = self.request.GET.get('search')
+# if search:
+# queryset = queryset.filter(name__icontains=search)
+#
+# dashboard_type = self.request.GET.get('type')
+# if dashboard_type:
+# queryset = queryset.filter(dashboard_type=dashboard_type)
+#
+# return queryset.order_by('-created_at')
+#
+# def get_context_data(self, **kwargs):
+# context = super().get_context_data(**kwargs)
+# context['title'] = 'Dashboards'
+# context['search'] = self.request.GET.get('search', '')
+# context['selected_type'] = self.request.GET.get('type', '')
+# return context
+#
+#
+# class DashboardDetailView(LoginRequiredMixin, PermissionRequiredMixin, DetailView):
+# """
+# View for dashboard details
+# """
+# model = Dashboard
+# template_name = 'analytics/dashboard_detail.html'
+# context_object_name = 'dashboard'
+# permission_required = 'analytics.view_dashboard'
+#
+# def get_queryset(self):
+# return Dashboard.objects.filter(tenant=self.request.user.tenant)
+#
+# def get_context_data(self, **kwargs):
+# context = super().get_context_data(**kwargs)
+# dashboard = self.object
+# context['title'] = dashboard.name
+# context['widgets'] = dashboard.widgets.filter(is_active=True).order_by('position_y', 'position_x')
+# context['can_edit'] = self.request.user.has_perm('analytics.change_dashboard')
+# return context
+#
+#
+# class ReportListView(LoginRequiredMixin, PermissionRequiredMixin, ListView):
+# """
+# View for listing reports
+# """
+# model = Report
+# template_name = 'analytics/report_list.html'
+# context_object_name = 'reports'
+# permission_required = 'analytics.view_report'
+# paginate_by = 20
+#
+# def get_queryset(self):
+# queryset = Report.objects.filter(tenant=self.request.user.tenant)
+#
+# # Apply filters
+# search = self.request.GET.get('search')
+# if search:
+# queryset = queryset.filter(name__icontains=search)
+#
+# report_type = self.request.GET.get('type')
+# if report_type:
+# queryset = queryset.filter(report_type=report_type)
+#
+# return queryset.order_by('-created_at')
+#
+# def get_context_data(self, **kwargs):
+# context = super().get_context_data(**kwargs)
+# context['title'] = 'Reports'
+# context['search'] = self.request.GET.get('search', '')
+# context['selected_type'] = self.request.GET.get('type', '')
+# return context
+#
+#
+# class ReportDetailView(LoginRequiredMixin, PermissionRequiredMixin, DetailView):
+# """
+# View for report details
+# """
+# model = Report
+# template_name = 'analytics/report_detail.html'
+# context_object_name = 'report'
+# permission_required = 'analytics.view_report'
+#
+# def get_queryset(self):
+# return Report.objects.filter(tenant=self.request.user.tenant)
+#
+# def get_context_data(self, **kwargs):
+# context = super().get_context_data(**kwargs)
+# report = self.object
+# context['title'] = report.name
+# context['executions'] = report.executions.order_by('-created_at')[:10]
+# context['can_generate'] = self.request.user.has_perm('analytics.can_generate_reports')
+# return context
+#
+#
+# # AJAX Views
+# @login_required
+# @permission_required('analytics.can_test_data_sources')
+# def test_data_source_ajax(request, data_source_id):
+# """AJAX view to test data source connection"""
+# if request.method == 'POST':
+# try:
+# data_source = DataSource.objects.get(
+# id=data_source_id,
+# tenant=request.user.tenant
+# )
+#
+# # Test connection
+# result = test_data_source_connection(data_source)
+#
+# return JsonResponse({
+# 'success': result['success'],
+# 'message': 'Connection successful' if result['success'] else result.get('error', 'Connection failed')
+# })
+# except DataSource.DoesNotExist:
+# return JsonResponse({
+# 'success': False,
+# 'message': 'Data source not found.'
+# })
+#
+# return JsonResponse({'success': False, 'message': 'Invalid request.'})
+#
+#
+# @login_required
+# @permission_required('analytics.can_calculate_metrics')
+# def calculate_metric_ajax(request, metric_id):
+# """AJAX view to calculate metric"""
+# if request.method == 'POST':
+# try:
+# metric = MetricDefinition.objects.get(
+# id=metric_id,
+# tenant=request.user.tenant
+# )
+#
+# # Start metric calculation
+# process = MetricCalculationFlow.start.run(
+# metric=metric,
+# calculate_now=True,
+# created_by=request.user
+# )
+#
+# return JsonResponse({
+# 'success': True,
+# 'message': 'Metric calculation initiated.'
+# })
+# except MetricDefinition.DoesNotExist:
+# return JsonResponse({
+# 'success': False,
+# 'message': 'Metric not found.'
+# })
+#
+# return JsonResponse({'success': False, 'message': 'Invalid request.'})
+#
+#
+# @login_required
+# def dashboard_data_ajax(request, dashboard_id):
+# """AJAX view to get dashboard data"""
+# try:
+# dashboard = Dashboard.objects.get(
+# id=dashboard_id,
+# tenant=request.user.tenant
+# )
+#
+# widgets_data = []
+# for widget in dashboard.widgets.filter(is_active=True):
+# widget_data = {
+# 'id': widget.id,
+# 'title': widget.title,
+# 'type': widget.widget_type,
+# 'position': {
+# 'x': widget.position_x,
+# 'y': widget.position_y,
+# 'width': widget.width,
+# 'height': widget.height
+# },
+# 'data': widget.get_data() # This would be implemented in the model
+# }
+# widgets_data.append(widget_data)
+#
+# return JsonResponse({
+# 'success': True,
+# 'dashboard': {
+# 'id': dashboard.id,
+# 'name': dashboard.name,
+# 'widgets': widgets_data
+# }
+# })
+# except Dashboard.DoesNotExist:
+# return JsonResponse({
+# 'success': False,
+# 'message': 'Dashboard not found.'
+# })
+#
+#
+# def test_data_source_connection(data_source):
+# """Test data source connection"""
+# try:
+# # Implement connection testing logic
+# return {'success': True}
+# except Exception as e:
+# return {'success': False, 'error': str(e)}
+#
diff --git a/appointments/__pycache__/flows.cpython-312.pyc b/appointments/__pycache__/flows.cpython-312.pyc
new file mode 100644
index 00000000..218b52df
Binary files /dev/null and b/appointments/__pycache__/flows.cpython-312.pyc differ
diff --git a/appointments/__pycache__/forms.cpython-312.pyc b/appointments/__pycache__/forms.cpython-312.pyc
index 18bfe31a..f0c15bd1 100644
Binary files a/appointments/__pycache__/forms.cpython-312.pyc and b/appointments/__pycache__/forms.cpython-312.pyc differ
diff --git a/appointments/__pycache__/views.cpython-312.pyc b/appointments/__pycache__/views.cpython-312.pyc
index 29ac94d5..8992cf75 100644
Binary files a/appointments/__pycache__/views.cpython-312.pyc and b/appointments/__pycache__/views.cpython-312.pyc differ
diff --git a/appointments/flows.py b/appointments/flows.py
new file mode 100644
index 00000000..f68bbf2e
--- /dev/null
+++ b/appointments/flows.py
@@ -0,0 +1,871 @@
+# """
+# Viewflow workflows for appointments app.
+# Provides appointment scheduling, confirmation, and queue management workflows.
+# """
+#
+# from viewflow import Flow, lock
+# from viewflow.base import this, flow_func
+# from viewflow.contrib import celery
+# from viewflow.decorators import flow_view
+# from viewflow.fields import CharField, ModelField
+# from viewflow.forms import ModelForm
+# from viewflow.views import CreateProcessView, UpdateProcessView
+# from viewflow.models import Process, Task
+# from django.contrib.auth.models import User
+# from django.urls import reverse_lazy
+# from django.utils import timezone
+# from django.db import transaction
+# from django.core.mail import send_mail
+#
+# from .models import AppointmentRequest, SlotAvailability, WaitingQueue, QueueEntry
+# from .views import (
+# AppointmentRequestView, AvailabilityCheckView, AppointmentSchedulingView,
+# AppointmentConfirmationView, ReminderView, CheckInView, QueueManagementView,
+# TelemedicineSetupView, AppointmentCompletionView, ReschedulingView,
+# CancellationView, NoShowHandlingView
+# )
+#
+#
+# class AppointmentSchedulingProcess(Process):
+# """
+# Viewflow process model for appointment scheduling
+# """
+# appointment_request = ModelField(AppointmentRequest, help_text='Associated appointment request')
+#
+# # Process status tracking
+# request_submitted = models.BooleanField(default=False)
+# availability_checked = models.BooleanField(default=False)
+# appointment_scheduled = models.BooleanField(default=False)
+# confirmation_sent = models.BooleanField(default=False)
+# reminders_scheduled = models.BooleanField(default=False)
+# patient_checked_in = models.BooleanField(default=False)
+# appointment_completed = models.BooleanField(default=False)
+#
+# class Meta:
+# verbose_name = 'Appointment Scheduling Process'
+# verbose_name_plural = 'Appointment Scheduling Processes'
+#
+#
+# class AppointmentSchedulingFlow(Flow):
+# """
+# Appointment Scheduling Workflow
+#
+# This flow manages the complete appointment lifecycle from
+# request through scheduling, confirmation, and completion.
+# """
+#
+# process_class = AppointmentSchedulingProcess
+#
+# # Flow definition
+# start = (
+# flow_func(this.start_appointment_scheduling)
+# .Next(this.submit_request)
+# )
+#
+# submit_request = (
+# flow_view(AppointmentRequestView)
+# .Permission('appointments.can_submit_requests')
+# .Next(this.check_availability)
+# )
+#
+# check_availability = (
+# flow_view(AvailabilityCheckView)
+# .Permission('appointments.can_check_availability')
+# .Next(this.schedule_appointment)
+# )
+#
+# schedule_appointment = (
+# flow_view(AppointmentSchedulingView)
+# .Permission('appointments.can_schedule_appointments')
+# .Next(this.send_confirmation)
+# )
+#
+# send_confirmation = (
+# flow_view(AppointmentConfirmationView)
+# .Permission('appointments.can_send_confirmations')
+# .Next(this.schedule_reminders)
+# )
+#
+# schedule_reminders = (
+# flow_func(this.setup_reminders)
+# .Next(this.check_in_patient)
+# )
+#
+# check_in_patient = (
+# flow_view(CheckInView)
+# .Permission('appointments.can_check_in_patients')
+# .Next(this.complete_appointment)
+# )
+#
+# complete_appointment = (
+# flow_func(this.finalize_appointment)
+# .Next(this.end)
+# )
+#
+# end = flow_func(this.end_appointment_scheduling)
+#
+# # Flow functions
+# def start_appointment_scheduling(self, activation):
+# """Initialize the appointment scheduling process"""
+# process = activation.process
+# appointment = process.appointment_request
+#
+# # Update appointment status
+# appointment.status = 'REQUESTED'
+# appointment.save()
+#
+# # Send notification to scheduling staff
+# self.notify_scheduling_staff(appointment)
+#
+# # Check for urgent appointments
+# if appointment.priority in ['HIGH', 'URGENT'] or appointment.urgency_score >= 8:
+# self.notify_urgent_appointment(appointment)
+#
+# def setup_reminders(self, activation):
+# """Setup appointment reminders"""
+# process = activation.process
+# appointment = process.appointment_request
+#
+# # Mark reminders as scheduled
+# process.reminders_scheduled = True
+# process.save()
+#
+# # Schedule reminder tasks
+# self.schedule_appointment_reminders(appointment)
+#
+# # Send immediate confirmation if telemedicine
+# if appointment.is_telemedicine:
+# self.setup_telemedicine_meeting(appointment)
+#
+# def finalize_appointment(self, activation):
+# """Finalize the appointment process"""
+# process = activation.process
+# appointment = process.appointment_request
+#
+# # Update appointment status
+# appointment.status = 'COMPLETED'
+# appointment.completed_at = timezone.now()
+# appointment.save()
+#
+# # Mark process as completed
+# process.appointment_completed = True
+# process.save()
+#
+# # Send completion notifications
+# self.notify_appointment_completion(appointment)
+#
+# # Update provider schedule
+# self.update_provider_schedule(appointment)
+#
+# # Generate follow-up recommendations
+# self.generate_follow_up_recommendations(appointment)
+#
+# def end_appointment_scheduling(self, activation):
+# """End the appointment scheduling workflow"""
+# process = activation.process
+#
+# # Generate appointment summary
+# self.generate_appointment_summary(process.appointment_request)
+#
+# # Helper methods
+# def notify_scheduling_staff(self, appointment):
+# """Notify scheduling staff of new appointment request"""
+# from django.contrib.auth.models import Group
+#
+# scheduling_staff = User.objects.filter(
+# groups__name='Scheduling Staff'
+# )
+#
+# for staff in scheduling_staff:
+# send_mail(
+# subject=f'New Appointment Request: {appointment.patient.get_full_name()}',
+# message=f'New {appointment.get_appointment_type_display()} appointment request for {appointment.specialty}.',
+# from_email='scheduling@hospital.com',
+# recipient_list=[staff.email],
+# fail_silently=True
+# )
+#
+# def notify_urgent_appointment(self, appointment):
+# """Notify of urgent appointment request"""
+# scheduling_managers = User.objects.filter(
+# groups__name='Scheduling Managers'
+# )
+#
+# for manager in scheduling_managers:
+# send_mail(
+# subject=f'URGENT Appointment Request: {appointment.patient.get_full_name()}',
+# message=f'{appointment.get_priority_display()} appointment request requires immediate attention.',
+# from_email='scheduling@hospital.com',
+# recipient_list=[manager.email],
+# fail_silently=True
+# )
+#
+# def schedule_appointment_reminders(self, appointment):
+# """Schedule appointment reminder tasks"""
+# if appointment.scheduled_datetime:
+# # Schedule 24-hour reminder
+# reminder_24h = appointment.scheduled_datetime - timedelta(hours=24)
+# if reminder_24h > timezone.now():
+# send_appointment_reminder.apply_async(
+# args=[appointment.id, '24_hour'],
+# eta=reminder_24h
+# )
+#
+# # Schedule 2-hour reminder
+# reminder_2h = appointment.scheduled_datetime - timedelta(hours=2)
+# if reminder_2h > timezone.now():
+# send_appointment_reminder.apply_async(
+# args=[appointment.id, '2_hour'],
+# eta=reminder_2h
+# )
+#
+# def setup_telemedicine_meeting(self, appointment):
+# """Setup telemedicine meeting details"""
+# # This would integrate with telemedicine platforms
+# pass
+#
+# def notify_appointment_completion(self, appointment):
+# """Notify appointment completion"""
+# # Notify patient
+# if appointment.patient.email:
+# send_mail(
+# subject='Appointment Completed',
+# message=f'Your appointment with {appointment.provider.get_full_name()} has been completed.',
+# from_email='appointments@hospital.com',
+# recipient_list=[appointment.patient.email],
+# fail_silently=True
+# )
+#
+# def update_provider_schedule(self, appointment):
+# """Update provider schedule after appointment"""
+# # This would update provider availability
+# pass
+#
+# def generate_follow_up_recommendations(self, appointment):
+# """Generate follow-up appointment recommendations"""
+# # This would analyze appointment and suggest follow-ups
+# pass
+#
+# def generate_appointment_summary(self, appointment):
+# """Generate appointment summary"""
+# # This would generate appointment summary report
+# pass
+#
+#
+# class AppointmentConfirmationProcess(Process):
+# """
+# Viewflow process model for appointment confirmation
+# """
+# appointment_request = ModelField(AppointmentRequest, help_text='Associated appointment request')
+#
+# # Process status tracking
+# confirmation_requested = models.BooleanField(default=False)
+# patient_contacted = models.BooleanField(default=False)
+# confirmation_received = models.BooleanField(default=False)
+# details_updated = models.BooleanField(default=False)
+# confirmation_completed = models.BooleanField(default=False)
+#
+# class Meta:
+# verbose_name = 'Appointment Confirmation Process'
+# verbose_name_plural = 'Appointment Confirmation Processes'
+#
+#
+# class AppointmentConfirmationFlow(Flow):
+# """
+# Appointment Confirmation Workflow
+#
+# This flow manages appointment confirmation including patient
+# contact, confirmation receipt, and detail updates.
+# """
+#
+# process_class = AppointmentConfirmationProcess
+#
+# # Flow definition
+# start = (
+# flow_func(this.start_confirmation)
+# .Next(this.request_confirmation)
+# )
+#
+# request_confirmation = (
+# flow_func(this.send_confirmation_request)
+# .Next(this.contact_patient)
+# )
+#
+# contact_patient = (
+# flow_view(PatientContactView)
+# .Permission('appointments.can_contact_patients')
+# .Next(this.receive_confirmation)
+# )
+#
+# receive_confirmation = (
+# flow_view(ConfirmationReceiptView)
+# .Permission('appointments.can_receive_confirmations')
+# .Next(this.update_details)
+# )
+#
+# update_details = (
+# flow_view(DetailUpdateView)
+# .Permission('appointments.can_update_details')
+# .Next(this.complete_confirmation)
+# )
+#
+# complete_confirmation = (
+# flow_func(this.finalize_confirmation)
+# .Next(this.end)
+# )
+#
+# end = flow_func(this.end_confirmation)
+#
+# # Flow functions
+# def start_confirmation(self, activation):
+# """Initialize the confirmation process"""
+# process = activation.process
+# appointment = process.appointment_request
+#
+# # Send confirmation request
+# self.send_confirmation_request(appointment)
+#
+# def send_confirmation_request(self, activation):
+# """Send confirmation request to patient"""
+# process = activation.process
+# appointment = process.appointment_request
+#
+# # Mark confirmation requested
+# process.confirmation_requested = True
+# process.save()
+#
+# # Send confirmation request via preferred method
+# self.send_confirmation_via_preferred_method(appointment)
+#
+# def finalize_confirmation(self, activation):
+# """Finalize the confirmation process"""
+# process = activation.process
+# appointment = process.appointment_request
+#
+# # Update appointment status
+# appointment.status = 'CONFIRMED'
+# appointment.save()
+#
+# # Mark process as completed
+# process.confirmation_completed = True
+# process.save()
+#
+# # Send confirmation completion notification
+# self.notify_confirmation_completion(appointment)
+#
+# def end_confirmation(self, activation):
+# """End the confirmation workflow"""
+# process = activation.process
+#
+# # Log confirmation completion
+# self.log_confirmation_completion(process.appointment_request)
+#
+# # Helper methods
+# def send_confirmation_via_preferred_method(self, appointment):
+# """Send confirmation via patient's preferred method"""
+# preferences = appointment.reminder_preferences
+#
+# if preferences.get('email', True) and appointment.patient.email:
+# self.send_email_confirmation(appointment)
+#
+# if preferences.get('sms', False) and appointment.patient.phone:
+# self.send_sms_confirmation(appointment)
+#
+# if preferences.get('phone', False):
+# self.schedule_phone_confirmation(appointment)
+#
+# def send_email_confirmation(self, appointment):
+# """Send email confirmation"""
+# send_mail(
+# subject='Appointment Confirmation Required',
+# message=f'Please confirm your appointment on {appointment.scheduled_datetime}.',
+# from_email='appointments@hospital.com',
+# recipient_list=[appointment.patient.email],
+# fail_silently=True
+# )
+#
+# def send_sms_confirmation(self, appointment):
+# """Send SMS confirmation"""
+# # This would integrate with SMS service
+# pass
+#
+# def schedule_phone_confirmation(self, appointment):
+# """Schedule phone confirmation call"""
+# # This would schedule a phone call task
+# pass
+#
+# def notify_confirmation_completion(self, appointment):
+# """Notify confirmation completion"""
+# # Notify scheduling staff
+# scheduling_staff = User.objects.filter(
+# groups__name='Scheduling Staff'
+# )
+#
+# for staff in scheduling_staff:
+# send_mail(
+# subject=f'Appointment Confirmed: {appointment.patient.get_full_name()}',
+# message=f'Patient has confirmed appointment for {appointment.scheduled_datetime}.',
+# from_email='appointments@hospital.com',
+# recipient_list=[staff.email],
+# fail_silently=True
+# )
+#
+# def log_confirmation_completion(self, appointment):
+# """Log confirmation completion"""
+# # This would log confirmation details
+# pass
+#
+#
+# class QueueManagementProcess(Process):
+# """
+# Viewflow process model for queue management
+# """
+# queue_entry = ModelField(QueueEntry, help_text='Associated queue entry')
+#
+# # Process status tracking
+# patient_queued = models.BooleanField(default=False)
+# position_assigned = models.BooleanField(default=False)
+# wait_time_estimated = models.BooleanField(default=False)
+# patient_called = models.BooleanField(default=False)
+# service_started = models.BooleanField(default=False)
+# service_completed = models.BooleanField(default=False)
+# queue_exited = models.BooleanField(default=False)
+#
+# class Meta:
+# verbose_name = 'Queue Management Process'
+# verbose_name_plural = 'Queue Management Processes'
+#
+#
+# class QueueManagementFlow(Flow):
+# """
+# Queue Management Workflow
+#
+# This flow manages patient flow through waiting queues
+# including position assignment and service coordination.
+# """
+#
+# process_class = QueueManagementProcess
+#
+# # Flow definition
+# start = (
+# flow_func(this.start_queue_management)
+# .Next(this.queue_patient)
+# )
+#
+# queue_patient = (
+# flow_view(PatientQueuingView)
+# .Permission('appointments.can_queue_patients')
+# .Next(this.assign_position)
+# )
+#
+# assign_position = (
+# flow_func(this.calculate_queue_position)
+# .Next(this.estimate_wait_time)
+# )
+#
+# estimate_wait_time = (
+# flow_func(this.calculate_wait_time)
+# .Next(this.call_patient)
+# )
+#
+# call_patient = (
+# flow_view(PatientCallingView)
+# .Permission('appointments.can_call_patients')
+# .Next(this.start_service)
+# )
+#
+# start_service = (
+# flow_view(ServiceStartView)
+# .Permission('appointments.can_start_service')
+# .Next(this.complete_service)
+# )
+#
+# complete_service = (
+# flow_view(ServiceCompletionView)
+# .Permission('appointments.can_complete_service')
+# .Next(this.exit_queue)
+# )
+#
+# exit_queue = (
+# flow_func(this.finalize_queue_management)
+# .Next(this.end)
+# )
+#
+# end = flow_func(this.end_queue_management)
+#
+# # Flow functions
+# def start_queue_management(self, activation):
+# """Initialize the queue management process"""
+# process = activation.process
+# entry = process.queue_entry
+#
+# # Update entry status
+# entry.status = 'WAITING'
+# entry.save()
+#
+# # Send queue notification
+# self.notify_queue_entry(entry)
+#
+# def calculate_queue_position(self, activation):
+# """Calculate and assign queue position"""
+# process = activation.process
+# entry = process.queue_entry
+#
+# # Calculate position based on priority and arrival time
+# position = self.determine_queue_position(entry)
+# entry.queue_position = position
+# entry.save()
+#
+# # Mark position assigned
+# process.position_assigned = True
+# process.save()
+#
+# # Update other queue positions
+# self.update_queue_positions(entry.queue)
+#
+# def calculate_wait_time(self, activation):
+# """Calculate estimated wait time"""
+# process = activation.process
+# entry = process.queue_entry
+#
+# # Calculate estimated service time
+# estimated_time = self.estimate_service_time(entry)
+# entry.estimated_service_time = estimated_time
+# entry.save()
+#
+# # Mark wait time estimated
+# process.wait_time_estimated = True
+# process.save()
+#
+# # Send wait time notification
+# self.notify_wait_time(entry)
+#
+# def finalize_queue_management(self, activation):
+# """Finalize the queue management process"""
+# process = activation.process
+# entry = process.queue_entry
+#
+# # Update entry status
+# entry.status = 'COMPLETED'
+# entry.served_at = timezone.now()
+# entry.save()
+#
+# # Mark process as completed
+# process.queue_exited = True
+# process.save()
+#
+# # Update queue metrics
+# self.update_queue_metrics(entry)
+#
+# # Notify next patient
+# self.notify_next_patient(entry.queue)
+#
+# def end_queue_management(self, activation):
+# """End the queue management workflow"""
+# process = activation.process
+#
+# # Generate queue summary
+# self.generate_queue_summary(process.queue_entry)
+#
+# # Helper methods
+# def notify_queue_entry(self, entry):
+# """Notify patient of queue entry"""
+# if entry.patient.email:
+# send_mail(
+# subject='Added to Waiting Queue',
+# message=f'You have been added to the {entry.queue.name} queue.',
+# from_email='appointments@hospital.com',
+# recipient_list=[entry.patient.email],
+# fail_silently=True
+# )
+#
+# def determine_queue_position(self, entry):
+# """Determine queue position based on priority"""
+# # This would implement priority-based positioning logic
+# return entry.queue.current_queue_size + 1
+#
+# def update_queue_positions(self, queue):
+# """Update positions for all entries in queue"""
+# entries = queue.queue_entries.filter(status='WAITING').order_by('priority_score', 'joined_at')
+# for i, entry in enumerate(entries, 1):
+# entry.queue_position = i
+# entry.save()
+#
+# def estimate_service_time(self, entry):
+# """Estimate service time for queue entry"""
+# queue = entry.queue
+# position = entry.queue_position
+# avg_service_time = queue.average_service_time_minutes
+#
+# estimated_minutes = position * avg_service_time
+# return timezone.now() + timedelta(minutes=estimated_minutes)
+#
+# def notify_wait_time(self, entry):
+# """Notify patient of estimated wait time"""
+# if entry.patient.email and entry.estimated_service_time:
+# wait_minutes = int((entry.estimated_service_time - timezone.now()).total_seconds() / 60)
+# send_mail(
+# subject='Queue Wait Time Update',
+# message=f'Your estimated wait time is {wait_minutes} minutes.',
+# from_email='appointments@hospital.com',
+# recipient_list=[entry.patient.email],
+# fail_silently=True
+# )
+#
+# def update_queue_metrics(self, entry):
+# """Update queue performance metrics"""
+# # This would update queue analytics
+# pass
+#
+# def notify_next_patient(self, queue):
+# """Notify next patient in queue"""
+# next_entry = queue.queue_entries.filter(
+# status='WAITING'
+# ).order_by('queue_position').first()
+#
+# if next_entry:
+# self.notify_patient_ready(next_entry)
+#
+# def notify_patient_ready(self, entry):
+# """Notify patient they are ready to be called"""
+# if entry.patient.email:
+# send_mail(
+# subject='Ready for Appointment',
+# message='You will be called shortly for your appointment.',
+# from_email='appointments@hospital.com',
+# recipient_list=[entry.patient.email],
+# fail_silently=True
+# )
+#
+# def generate_queue_summary(self, entry):
+# """Generate queue management summary"""
+# # This would generate queue analytics
+# pass
+#
+#
+# class TelemedicineSetupProcess(Process):
+# """
+# Viewflow process model for telemedicine setup
+# """
+# appointment_request = ModelField(AppointmentRequest, help_text='Associated appointment request')
+#
+# # Process status tracking
+# platform_selected = models.BooleanField(default=False)
+# meeting_created = models.BooleanField(default=False)
+# credentials_sent = models.BooleanField(default=False)
+# technical_check_completed = models.BooleanField(default=False)
+# meeting_ready = models.BooleanField(default=False)
+#
+# class Meta:
+# verbose_name = 'Telemedicine Setup Process'
+# verbose_name_plural = 'Telemedicine Setup Processes'
+#
+#
+# class TelemedicineSetupFlow(Flow):
+# """
+# Telemedicine Setup Workflow
+#
+# This flow manages telemedicine appointment setup including
+# platform selection, meeting creation, and technical verification.
+# """
+#
+# process_class = TelemedicineSetupProcess
+#
+# # Flow definition
+# start = (
+# flow_func(this.start_telemedicine_setup)
+# .Next(this.select_platform)
+# )
+#
+# select_platform = (
+# flow_view(PlatformSelectionView)
+# .Permission('appointments.can_select_platforms')
+# .Next(this.create_meeting)
+# )
+#
+# create_meeting = (
+# flow_view(MeetingCreationView)
+# .Permission('appointments.can_create_meetings')
+# .Next(this.send_credentials)
+# )
+#
+# send_credentials = (
+# flow_view(CredentialSendingView)
+# .Permission('appointments.can_send_credentials')
+# .Next(this.technical_check)
+# )
+#
+# technical_check = (
+# flow_view(TechnicalCheckView)
+# .Permission('appointments.can_perform_technical_checks')
+# .Next(this.finalize_setup)
+# )
+#
+# finalize_setup = (
+# flow_func(this.complete_telemedicine_setup)
+# .Next(this.end)
+# )
+#
+# end = flow_func(this.end_telemedicine_setup)
+#
+# # Flow functions
+# def start_telemedicine_setup(self, activation):
+# """Initialize the telemedicine setup process"""
+# process = activation.process
+# appointment = process.appointment_request
+#
+# # Mark as telemedicine appointment
+# appointment.is_telemedicine = True
+# appointment.save()
+#
+# # Send setup notification
+# self.notify_telemedicine_setup(appointment)
+#
+# def complete_telemedicine_setup(self, activation):
+# """Finalize the telemedicine setup process"""
+# process = activation.process
+# appointment = process.appointment_request
+#
+# # Mark meeting as ready
+# process.meeting_ready = True
+# process.save()
+#
+# # Send final meeting details
+# self.send_final_meeting_details(appointment)
+#
+# # Schedule pre-meeting reminder
+# self.schedule_pre_meeting_reminder(appointment)
+#
+# def end_telemedicine_setup(self, activation):
+# """End the telemedicine setup workflow"""
+# process = activation.process
+#
+# # Log setup completion
+# self.log_telemedicine_setup(process.appointment_request)
+#
+# # Helper methods
+# def notify_telemedicine_setup(self, appointment):
+# """Notify patient of telemedicine setup"""
+# if appointment.patient.email:
+# send_mail(
+# subject='Telemedicine Appointment Setup',
+# message='Your telemedicine appointment is being set up. You will receive meeting details shortly.',
+# from_email='telemedicine@hospital.com',
+# recipient_list=[appointment.patient.email],
+# fail_silently=True
+# )
+#
+# def send_final_meeting_details(self, appointment):
+# """Send final meeting details to patient"""
+# if appointment.patient.email:
+# send_mail(
+# subject='Telemedicine Meeting Details',
+# message=f'Meeting URL: {appointment.meeting_url}\nMeeting ID: {appointment.meeting_id}',
+# from_email='telemedicine@hospital.com',
+# recipient_list=[appointment.patient.email],
+# fail_silently=True
+# )
+#
+# def schedule_pre_meeting_reminder(self, appointment):
+# """Schedule pre-meeting reminder"""
+# if appointment.scheduled_datetime:
+# reminder_time = appointment.scheduled_datetime - timedelta(minutes=15)
+# if reminder_time > timezone.now():
+# send_telemedicine_reminder.apply_async(
+# args=[appointment.id],
+# eta=reminder_time
+# )
+#
+# def log_telemedicine_setup(self, appointment):
+# """Log telemedicine setup completion"""
+# # This would log setup details
+# pass
+#
+#
+# # Celery tasks for background processing
+# @celery.job
+# def send_appointment_reminder(appointment_id, reminder_type):
+# """Background task to send appointment reminders"""
+# try:
+# appointment = AppointmentRequest.objects.get(id=appointment_id)
+#
+# if reminder_type == '24_hour':
+# subject = 'Appointment Reminder - Tomorrow'
+# message = f'Reminder: You have an appointment tomorrow at {appointment.scheduled_datetime}.'
+# elif reminder_type == '2_hour':
+# subject = 'Appointment Reminder - 2 Hours'
+# message = f'Reminder: You have an appointment in 2 hours at {appointment.scheduled_datetime}.'
+#
+# if appointment.patient.email:
+# send_mail(
+# subject=subject,
+# message=message,
+# from_email='appointments@hospital.com',
+# recipient_list=[appointment.patient.email],
+# fail_silently=True
+# )
+#
+# return True
+# except Exception:
+# return False
+#
+#
+# @celery.job
+# def send_telemedicine_reminder(appointment_id):
+# """Background task to send telemedicine pre-meeting reminder"""
+# try:
+# appointment = AppointmentRequest.objects.get(id=appointment_id)
+#
+# if appointment.patient.email:
+# send_mail(
+# subject='Telemedicine Meeting Starting Soon',
+# message=f'Your telemedicine appointment starts in 15 minutes. Meeting URL: {appointment.meeting_url}',
+# from_email='telemedicine@hospital.com',
+# recipient_list=[appointment.patient.email],
+# fail_silently=True
+# )
+#
+# return True
+# except Exception:
+# return False
+#
+#
+# @celery.job
+# def auto_confirm_appointments():
+# """Background task to automatically confirm appointments"""
+# try:
+# # This would implement auto-confirmation logic
+# return True
+# except Exception:
+# return False
+#
+#
+# @celery.job
+# def manage_no_shows():
+# """Background task to manage no-show appointments"""
+# try:
+# # This would identify and handle no-show appointments
+# return True
+# except Exception:
+# return False
+#
+#
+# @celery.job
+# def optimize_schedules():
+# """Background task to optimize provider schedules"""
+# try:
+# # This would implement schedule optimization
+# return True
+# except Exception:
+# return False
+#
+#
+# @celery.job
+# def update_queue_positions():
+# """Background task to update queue positions"""
+# try:
+# # This would update queue positions and wait times
+# return True
+# except Exception:
+# return False
+#
diff --git a/appointments/forms.py b/appointments/forms.py
index 2d353f5c..776859a9 100644
--- a/appointments/forms.py
+++ b/appointments/forms.py
@@ -439,3 +439,751 @@ class SlotSearchForm(forms.Form):
role__in=['PHYSICIAN', 'NURSE', 'NURSE_PRACTITIONER', 'PHYSICIAN_ASSISTANT']
).order_by('last_name', 'first_name')
+
+# from django import forms
+# from django.core.exceptions import ValidationError
+# from django.utils import timezone
+# from django.contrib.auth.models import User
+# from crispy_forms.helper import FormHelper
+# from crispy_forms.layout import Layout, Fieldset, Submit, Row, Column, HTML, Div
+# from crispy_forms.bootstrap import FormActions
+# from datetime import datetime, timedelta
+#
+# from .models import Appointment, AppointmentConfirmation, Queue, TelemedicineSession
+# from patients.models import Patient
+# from core.models import Department
+#
+#
+# class AppointmentSchedulingForm(forms.ModelForm):
+# """
+# Form for appointment scheduling
+# """
+# patient_search = forms.CharField(
+# required=False,
+# widget=forms.TextInput(attrs={
+# 'class': 'form-control',
+# 'placeholder': 'Search patient by name, ID, or phone...',
+# 'data-toggle': 'patient-search'
+# })
+# )
+# preferred_time_1 = forms.TimeField(
+# required=False,
+# widget=forms.TimeInput(attrs={'class': 'form-control', 'type': 'time'})
+# )
+# preferred_time_2 = forms.TimeField(
+# required=False,
+# widget=forms.TimeInput(attrs={'class': 'form-control', 'type': 'time'})
+# )
+# preferred_time_3 = forms.TimeField(
+# required=False,
+# widget=forms.TimeInput(attrs={'class': 'form-control', 'type': 'time'})
+# )
+# special_instructions = forms.CharField(
+# required=False,
+# widget=forms.Textarea(attrs={'class': 'form-control', 'rows': 3})
+# )
+# send_confirmation = forms.BooleanField(
+# required=False,
+# initial=True,
+# widget=forms.CheckboxInput(attrs={'class': 'form-check-input'})
+# )
+# send_reminder = forms.BooleanField(
+# required=False,
+# initial=True,
+# widget=forms.CheckboxInput(attrs={'class': 'form-check-input'})
+# )
+#
+# class Meta:
+# model = Appointment
+# fields = [
+# 'patient', 'provider', 'department', 'appointment_type',
+# 'appointment_date', 'appointment_time', 'duration',
+# 'urgency', 'reason', 'notes', 'special_instructions',
+# 'send_confirmation', 'send_reminder'
+# ]
+# widgets = {
+# 'patient': forms.Select(attrs={'class': 'form-control'}),
+# 'provider': forms.Select(attrs={'class': 'form-control'}),
+# 'department': forms.Select(attrs={'class': 'form-control'}),
+# 'appointment_type': forms.Select(attrs={'class': 'form-control'}),
+# 'appointment_date': forms.DateInput(attrs={'class': 'form-control', 'type': 'date'}),
+# 'appointment_time': forms.TimeInput(attrs={'class': 'form-control', 'type': 'time'}),
+# 'duration': forms.NumberInput(attrs={'class': 'form-control'}),
+# 'urgency': forms.Select(attrs={'class': 'form-control'}),
+# 'reason': forms.TextInput(attrs={'class': 'form-control'}),
+# 'notes': forms.Textarea(attrs={'class': 'form-control', 'rows': 3})
+# }
+#
+# def __init__(self, *args, **kwargs):
+# tenant = kwargs.pop('tenant', None)
+# super().__init__(*args, **kwargs)
+#
+# if tenant:
+# self.fields['patient'].queryset = Patient.objects.filter(tenant=tenant)
+# self.fields['provider'].queryset = User.objects.filter(
+# tenant=tenant,
+# groups__name__in=['Doctors', 'Nurses', 'Specialists']
+# )
+# self.fields['department'].queryset = Department.objects.filter(tenant=tenant)
+#
+# # Set minimum date to today
+# self.fields['appointment_date'].widget.attrs['min'] = timezone.now().date().isoformat()
+#
+# self.helper = FormHelper()
+# self.helper.layout = Layout(
+# Fieldset(
+# 'Patient Information',
+# 'patient_search',
+# 'patient'
+# ),
+# Fieldset(
+# 'Appointment Details',
+# Row(
+# Column('provider', css_class='form-group col-md-6 mb-0'),
+# Column('department', css_class='form-group col-md-6 mb-0'),
+# css_class='form-row'
+# ),
+# Row(
+# Column('appointment_type', css_class='form-group col-md-6 mb-0'),
+# Column('urgency', css_class='form-group col-md-6 mb-0'),
+# css_class='form-row'
+# ),
+# Row(
+# Column('appointment_date', css_class='form-group col-md-4 mb-0'),
+# Column('appointment_time', css_class='form-group col-md-4 mb-0'),
+# Column('duration', css_class='form-group col-md-4 mb-0'),
+# css_class='form-row'
+# ),
+# 'reason',
+# 'notes',
+# 'special_instructions'
+# ),
+# Fieldset(
+# 'Preferred Times (Alternative Options)',
+# Row(
+# Column('preferred_time_1', css_class='form-group col-md-4 mb-0'),
+# Column('preferred_time_2', css_class='form-group col-md-4 mb-0'),
+# Column('preferred_time_3', css_class='form-group col-md-4 mb-0'),
+# css_class='form-row'
+# )
+# ),
+# Fieldset(
+# 'Notifications',
+# HTML(''),
+# 'send_confirmation',
+# HTML(
+# ''),
+# HTML('
'),
+# HTML(''),
+# 'send_reminder',
+# HTML(''),
+# HTML('
')
+# ),
+# FormActions(
+# Submit('submit', 'Schedule Appointment', css_class='btn btn-primary'),
+# HTML('Cancel')
+# )
+# )
+#
+# def clean(self):
+# cleaned_data = super().clean()
+# appointment_date = cleaned_data.get('appointment_date')
+# appointment_time = cleaned_data.get('appointment_time')
+# provider = cleaned_data.get('provider')
+#
+# if appointment_date and appointment_time:
+# appointment_datetime = datetime.combine(appointment_date, appointment_time)
+#
+# # Check if appointment is in the past
+# if appointment_datetime < timezone.now():
+# raise ValidationError('Appointment cannot be scheduled in the past.')
+#
+# # Check provider availability
+# if provider and self.check_provider_conflict(provider, appointment_datetime):
+# raise ValidationError('Provider is not available at the selected time.')
+#
+# return cleaned_data
+#
+# def check_provider_conflict(self, provider, appointment_datetime):
+# """Check if provider has conflicting appointments"""
+# duration = self.cleaned_data.get('duration', 30)
+# end_time = appointment_datetime + timedelta(minutes=duration)
+#
+# conflicts = Appointment.objects.filter(
+# provider=provider,
+# appointment_date=appointment_datetime.date(),
+# status__in=['scheduled', 'confirmed', 'in_progress']
+# ).exclude(id=self.instance.id if self.instance else None)
+#
+# for conflict in conflicts:
+# conflict_start = datetime.combine(conflict.appointment_date, conflict.appointment_time)
+# conflict_end = conflict_start + timedelta(minutes=conflict.duration)
+#
+# if (appointment_datetime < conflict_end and end_time > conflict_start):
+# return True
+#
+# return False
+#
+#
+# class AppointmentConfirmationForm(forms.ModelForm):
+# """
+# Form for appointment confirmation
+# """
+# confirmation_method = forms.ChoiceField(
+# choices=[
+# ('phone', 'Phone Call'),
+# ('email', 'Email'),
+# ('sms', 'SMS'),
+# ('in_person', 'In Person'),
+# ('online', 'Online Portal')
+# ],
+# required=True,
+# widget=forms.Select(attrs={'class': 'form-control'})
+# )
+# contact_attempts = forms.IntegerField(
+# initial=1,
+# min_value=1,
+# max_value=5,
+# widget=forms.NumberInput(attrs={'class': 'form-control'})
+# )
+# confirmation_notes = forms.CharField(
+# required=False,
+# widget=forms.Textarea(attrs={'class': 'form-control', 'rows': 3})
+# )
+# reschedule_requested = forms.BooleanField(
+# required=False,
+# widget=forms.CheckboxInput(attrs={'class': 'form-check-input'})
+# )
+# new_preferred_date = forms.DateField(
+# required=False,
+# widget=forms.DateInput(attrs={'class': 'form-control', 'type': 'date'})
+# )
+# new_preferred_time = forms.TimeField(
+# required=False,
+# widget=forms.TimeInput(attrs={'class': 'form-control', 'type': 'time'})
+# )
+#
+# class Meta:
+# model = AppointmentConfirmation
+# fields = [
+# 'confirmation_method', 'contact_attempts', 'confirmation_notes',
+# 'reschedule_requested', 'new_preferred_date', 'new_preferred_time'
+# ]
+#
+# def __init__(self, *args, **kwargs):
+# appointment = kwargs.pop('appointment', None)
+# super().__init__(*args, **kwargs)
+#
+# self.appointment = appointment
+#
+# self.helper = FormHelper()
+# self.helper.layout = Layout(
+# Fieldset(
+# 'Confirmation Details',
+# Row(
+# Column('confirmation_method', css_class='form-group col-md-6 mb-0'),
+# Column('contact_attempts', css_class='form-group col-md-6 mb-0'),
+# css_class='form-row'
+# ),
+# 'confirmation_notes'
+# ),
+# Fieldset(
+# 'Reschedule Request',
+# HTML(''),
+# 'reschedule_requested',
+# HTML(
+# ''),
+# HTML('
'),
+# Row(
+# Column('new_preferred_date', css_class='form-group col-md-6 mb-0'),
+# Column('new_preferred_time', css_class='form-group col-md-6 mb-0'),
+# css_class='form-row'
+# )
+# ),
+# FormActions(
+# Submit('submit', 'Confirm Appointment', css_class='btn btn-primary'),
+# HTML(
+# 'Cancel')
+# )
+# )
+#
+# def clean(self):
+# cleaned_data = super().clean()
+# reschedule_requested = cleaned_data.get('reschedule_requested')
+# new_preferred_date = cleaned_data.get('new_preferred_date')
+# new_preferred_time = cleaned_data.get('new_preferred_time')
+#
+# if reschedule_requested:
+# if not new_preferred_date:
+# raise ValidationError('New preferred date is required when reschedule is requested.')
+# if not new_preferred_time:
+# raise ValidationError('New preferred time is required when reschedule is requested.')
+#
+# return cleaned_data
+#
+#
+# class QueueManagementForm(forms.ModelForm):
+# """
+# Form for queue management
+# """
+# estimated_wait_time = forms.IntegerField(
+# required=False,
+# widget=forms.NumberInput(attrs={'class': 'form-control'})
+# )
+# priority_adjustment = forms.ChoiceField(
+# choices=[
+# ('none', 'No Change'),
+# ('increase', 'Increase Priority'),
+# ('decrease', 'Decrease Priority')
+# ],
+# required=False,
+# widget=forms.Select(attrs={'class': 'form-control'})
+# )
+# queue_notes = forms.CharField(
+# required=False,
+# widget=forms.Textarea(attrs={'class': 'form-control', 'rows': 3})
+# )
+# notify_patient = forms.BooleanField(
+# required=False,
+# initial=True,
+# widget=forms.CheckboxInput(attrs={'class': 'form-check-input'})
+# )
+#
+# class Meta:
+# model = Queue
+# fields = [
+# 'queue_type', 'priority', 'estimated_wait_time',
+# 'priority_adjustment', 'queue_notes', 'notify_patient'
+# ]
+# widgets = {
+# 'queue_type': forms.Select(attrs={'class': 'form-control'}),
+# 'priority': forms.Select(attrs={'class': 'form-control'})
+# }
+#
+# def __init__(self, *args, **kwargs):
+# super().__init__(*args, **kwargs)
+#
+# self.helper = FormHelper()
+# self.helper.layout = Layout(
+# Fieldset(
+# 'Queue Configuration',
+# Row(
+# Column('queue_type', css_class='form-group col-md-6 mb-0'),
+# Column('priority', css_class='form-group col-md-6 mb-0'),
+# css_class='form-row'
+# ),
+# Row(
+# Column('estimated_wait_time', css_class='form-group col-md-6 mb-0'),
+# Column('priority_adjustment', css_class='form-group col-md-6 mb-0'),
+# css_class='form-row'
+# ),
+# 'queue_notes'
+# ),
+# Fieldset(
+# 'Notifications',
+# HTML(''),
+# 'notify_patient',
+# HTML(''),
+# HTML('
')
+# ),
+# FormActions(
+# Submit('submit', 'Update Queue', css_class='btn btn-primary'),
+# HTML('Cancel')
+# )
+# )
+#
+#
+# class TelemedicineSetupForm(forms.ModelForm):
+# """
+# Form for telemedicine session setup
+# """
+# platform = forms.ChoiceField(
+# choices=[
+# ('zoom', 'Zoom'),
+# ('teams', 'Microsoft Teams'),
+# ('webex', 'Cisco Webex'),
+# ('meet', 'Google Meet'),
+# ('custom', 'Custom Platform')
+# ],
+# required=True,
+# widget=forms.Select(attrs={'class': 'form-control'})
+# )
+# test_connection = forms.BooleanField(
+# required=False,
+# initial=True,
+# widget=forms.CheckboxInput(attrs={'class': 'form-check-input'})
+# )
+# send_instructions = forms.BooleanField(
+# required=False,
+# initial=True,
+# widget=forms.CheckboxInput(attrs={'class': 'form-check-input'})
+# )
+# backup_phone = forms.CharField(
+# required=False,
+# widget=forms.TextInput(attrs={'class': 'form-control'})
+# )
+# technical_support_contact = forms.CharField(
+# required=False,
+# widget=forms.TextInput(attrs={'class': 'form-control'})
+# )
+# session_recording = forms.BooleanField(
+# required=False,
+# widget=forms.CheckboxInput(attrs={'class': 'form-check-input'})
+# )
+#
+# class Meta:
+# model = TelemedicineSession
+# fields = [
+# 'platform', 'meeting_url', 'meeting_id', 'meeting_password',
+# 'test_connection', 'send_instructions', 'backup_phone',
+# 'technical_support_contact', 'session_recording'
+# ]
+# widgets = {
+# 'meeting_url': forms.URLInput(attrs={'class': 'form-control'}),
+# 'meeting_id': forms.TextInput(attrs={'class': 'form-control'}),
+# 'meeting_password': forms.TextInput(attrs={'class': 'form-control'})
+# }
+#
+# def __init__(self, *args, **kwargs):
+# appointment = kwargs.pop('appointment', None)
+# super().__init__(*args, **kwargs)
+#
+# self.appointment = appointment
+#
+# self.helper = FormHelper()
+# self.helper.layout = Layout(
+# Fieldset(
+# 'Platform Configuration',
+# 'platform',
+# 'meeting_url',
+# Row(
+# Column('meeting_id', css_class='form-group col-md-6 mb-0'),
+# Column('meeting_password', css_class='form-group col-md-6 mb-0'),
+# css_class='form-row'
+# )
+# ),
+# Fieldset(
+# 'Support Information',
+# Row(
+# Column('backup_phone', css_class='form-group col-md-6 mb-0'),
+# Column('technical_support_contact', css_class='form-group col-md-6 mb-0'),
+# css_class='form-row'
+# )
+# ),
+# Fieldset(
+# 'Session Options',
+# HTML(''),
+# 'test_connection',
+# HTML(
+# ''),
+# HTML('
'),
+# HTML(''),
+# 'send_instructions',
+# HTML(
+# ''),
+# HTML('
'),
+# HTML(''),
+# 'session_recording',
+# HTML(
+# ''),
+# HTML('
')
+# ),
+# FormActions(
+# Submit('submit', 'Setup Telemedicine', css_class='btn btn-primary'),
+# HTML(
+# 'Cancel')
+# )
+# )
+#
+# def clean_meeting_url(self):
+# meeting_url = self.cleaned_data.get('meeting_url')
+# platform = self.cleaned_data.get('platform')
+#
+# if platform and meeting_url:
+# # Validate URL format based on platform
+# if platform == 'zoom' and 'zoom.us' not in meeting_url:
+# raise ValidationError('Invalid Zoom meeting URL format.')
+# elif platform == 'teams' and 'teams.microsoft.com' not in meeting_url:
+# raise ValidationError('Invalid Microsoft Teams meeting URL format.')
+# elif platform == 'webex' and 'webex.com' not in meeting_url:
+# raise ValidationError('Invalid Webex meeting URL format.')
+# elif platform == 'meet' and 'meet.google.com' not in meeting_url:
+# raise ValidationError('Invalid Google Meet URL format.')
+#
+# return meeting_url
+#
+#
+# class AppointmentRescheduleForm(forms.Form):
+# """
+# Form for appointment rescheduling
+# """
+# new_date = forms.DateField(
+# required=True,
+# widget=forms.DateInput(attrs={'class': 'form-control', 'type': 'date'})
+# )
+# new_time = forms.TimeField(
+# required=True,
+# widget=forms.TimeInput(attrs={'class': 'form-control', 'type': 'time'})
+# )
+# new_provider = forms.ModelChoiceField(
+# queryset=None,
+# required=False,
+# widget=forms.Select(attrs={'class': 'form-control'})
+# )
+# reschedule_reason = forms.ChoiceField(
+# choices=[
+# ('patient_request', 'Patient Request'),
+# ('provider_unavailable', 'Provider Unavailable'),
+# ('emergency', 'Emergency'),
+# ('equipment_issue', 'Equipment Issue'),
+# ('other', 'Other')
+# ],
+# required=True,
+# widget=forms.Select(attrs={'class': 'form-control'})
+# )
+# notes = forms.CharField(
+# required=False,
+# widget=forms.Textarea(attrs={'class': 'form-control', 'rows': 3})
+# )
+# notify_patient = forms.BooleanField(
+# required=False,
+# initial=True,
+# widget=forms.CheckboxInput(attrs={'class': 'form-check-input'})
+# )
+#
+# def __init__(self, *args, **kwargs):
+# tenant = kwargs.pop('tenant', None)
+# appointment = kwargs.pop('appointment', None)
+# super().__init__(*args, **kwargs)
+#
+# if tenant:
+# self.fields['new_provider'].queryset = User.objects.filter(
+# tenant=tenant,
+# groups__name__in=['Doctors', 'Nurses', 'Specialists']
+# )
+#
+# # Set minimum date to today
+# self.fields['new_date'].widget.attrs['min'] = timezone.now().date().isoformat()
+#
+# self.helper = FormHelper()
+# self.helper.layout = Layout(
+# Fieldset(
+# 'New Appointment Details',
+# Row(
+# Column('new_date', css_class='form-group col-md-6 mb-0'),
+# Column('new_time', css_class='form-group col-md-6 mb-0'),
+# css_class='form-row'
+# ),
+# 'new_provider'
+# ),
+# Fieldset(
+# 'Reschedule Information',
+# 'reschedule_reason',
+# 'notes'
+# ),
+# Fieldset(
+# 'Notifications',
+# HTML(''),
+# 'notify_patient',
+# HTML(''),
+# HTML('
')
+# ),
+# FormActions(
+# Submit('submit', 'Reschedule Appointment', css_class='btn btn-primary'),
+# HTML(
+# 'Cancel')
+# )
+# )
+#
+#
+# class AppointmentCancellationForm(forms.Form):
+# """
+# Form for appointment cancellation
+# """
+# cancellation_reason = forms.ChoiceField(
+# choices=[
+# ('patient_request', 'Patient Request'),
+# ('provider_unavailable', 'Provider Unavailable'),
+# ('patient_no_show', 'Patient No Show'),
+# ('emergency', 'Emergency'),
+# ('equipment_failure', 'Equipment Failure'),
+# ('other', 'Other')
+# ],
+# required=True,
+# widget=forms.Select(attrs={'class': 'form-control'})
+# )
+# cancellation_notes = forms.CharField(
+# required=False,
+# widget=forms.Textarea(attrs={'class': 'form-control', 'rows': 3})
+# )
+# offer_reschedule = forms.BooleanField(
+# required=False,
+# initial=True,
+# widget=forms.CheckboxInput(attrs={'class': 'form-check-input'})
+# )
+# notify_patient = forms.BooleanField(
+# required=False,
+# initial=True,
+# widget=forms.CheckboxInput(attrs={'class': 'form-check-input'})
+# )
+# refund_required = forms.BooleanField(
+# required=False,
+# widget=forms.CheckboxInput(attrs={'class': 'form-check-input'})
+# )
+#
+# def __init__(self, *args, **kwargs):
+# super().__init__(*args, **kwargs)
+#
+# self.helper = FormHelper()
+# self.helper.layout = Layout(
+# Fieldset(
+# 'Cancellation Details',
+# 'cancellation_reason',
+# 'cancellation_notes'
+# ),
+# Fieldset(
+# 'Follow-up Actions',
+# HTML(''),
+# 'offer_reschedule',
+# HTML(
+# ''),
+# HTML('
'),
+# HTML(''),
+# 'notify_patient',
+# HTML(''),
+# HTML('
'),
+# HTML(''),
+# 'refund_required',
+# HTML(''),
+# HTML('
')
+# ),
+# FormActions(
+# Submit('submit', 'Cancel Appointment', css_class='btn btn-danger'),
+# HTML(
+# 'Back')
+# )
+# )
+#
+#
+# class AppointmentCheckInForm(forms.Form):
+# """
+# Form for appointment check-in
+# """
+# arrival_time = forms.TimeField(
+# initial=timezone.now().time(),
+# widget=forms.TimeInput(attrs={'class': 'form-control', 'type': 'time'})
+# )
+# insurance_verified = forms.BooleanField(
+# required=False,
+# widget=forms.CheckboxInput(attrs={'class': 'form-check-input'})
+# )
+# copay_collected = forms.BooleanField(
+# required=False,
+# widget=forms.CheckboxInput(attrs={'class': 'form-check-input'})
+# )
+# forms_completed = forms.BooleanField(
+# required=False,
+# widget=forms.CheckboxInput(attrs={'class': 'form-check-input'})
+# )
+# vitals_required = forms.BooleanField(
+# required=False,
+# widget=forms.CheckboxInput(attrs={'class': 'form-check-input'})
+# )
+# special_needs = forms.CharField(
+# required=False,
+# widget=forms.Textarea(attrs={'class': 'form-control', 'rows': 2})
+# )
+#
+# def __init__(self, *args, **kwargs):
+# super().__init__(*args, **kwargs)
+#
+# self.helper = FormHelper()
+# self.helper.layout = Layout(
+# Fieldset(
+# 'Check-in Information',
+# 'arrival_time',
+# 'special_needs'
+# ),
+# Fieldset(
+# 'Pre-visit Tasks',
+# HTML(''),
+# 'insurance_verified',
+# HTML(''),
+# HTML('
'),
+# HTML(''),
+# 'copay_collected',
+# HTML(''),
+# HTML('
'),
+# HTML(''),
+# 'forms_completed',
+# HTML(''),
+# HTML('
'),
+# HTML(''),
+# 'vitals_required',
+# HTML(''),
+# HTML('
')
+# ),
+# FormActions(
+# Submit('submit', 'Check In Patient', css_class='btn btn-primary'),
+# HTML(
+# 'Cancel')
+# )
+# )
+#
+#
+# class BulkAppointmentForm(forms.Form):
+# """
+# Form for bulk appointment operations
+# """
+# action = forms.ChoiceField(
+# choices=[
+# ('confirm', 'Confirm Appointments'),
+# ('reschedule', 'Reschedule Appointments'),
+# ('cancel', 'Cancel Appointments'),
+# ('send_reminders', 'Send Reminders')
+# ],
+# required=True,
+# widget=forms.Select(attrs={'class': 'form-control'})
+# )
+# appointment_ids = forms.CharField(
+# widget=forms.HiddenInput()
+# )
+# bulk_date = forms.DateField(
+# required=False,
+# widget=forms.DateInput(attrs={'class': 'form-control', 'type': 'date'})
+# )
+# bulk_reason = forms.CharField(
+# required=False,
+# widget=forms.Textarea(attrs={'class': 'form-control', 'rows': 3})
+# )
+# notify_patients = forms.BooleanField(
+# required=False,
+# initial=True,
+# widget=forms.CheckboxInput(attrs={'class': 'form-check-input'})
+# )
+#
+# def __init__(self, *args, **kwargs):
+# super().__init__(*args, **kwargs)
+#
+# self.helper = FormHelper()
+# self.helper.layout = Layout(
+# 'appointment_ids',
+# Fieldset(
+# 'Bulk Operation',
+# 'action',
+# 'bulk_date',
+# 'bulk_reason'
+# ),
+# Fieldset(
+# 'Notifications',
+# HTML(''),
+# 'notify_patients',
+# HTML(''),
+# HTML('
')
+# ),
+# FormActions(
+# Submit('submit', 'Execute Bulk Operation', css_class='btn btn-primary'),
+# HTML('Cancel')
+# )
+# )
+#
diff --git a/appointments/views.py b/appointments/views.py
index eb643ade..d3ed1966 100644
--- a/appointments/views.py
+++ b/appointments/views.py
@@ -3209,3 +3209,907 @@ def reschedule_appointment(request, appointment_id):
# 'appointment': session.appointment
# })
#
+
+
+# from django.shortcuts import render, redirect, get_object_or_404
+# from django.contrib.auth.decorators import login_required, permission_required
+# from django.contrib.auth.mixins import LoginRequiredMixin, PermissionRequiredMixin
+# from django.contrib import messages
+# from django.views.generic import (
+# CreateView, UpdateView, DeleteView, DetailView, ListView, FormView
+# )
+# from django.urls import reverse_lazy, reverse
+# from django.http import JsonResponse, HttpResponse
+# from django.utils import timezone
+# from django.db import transaction
+# from django.core.mail import send_mail
+# from django.conf import settings
+# from django.db.models import Q, Count
+# from viewflow.views import CreateProcessView, UpdateProcessView
+# from datetime import datetime, timedelta
+# import json
+#
+# from .models import Appointment, AppointmentConfirmation, Queue, TelemedicineSession
+# from .forms import (
+# AppointmentSchedulingForm, AppointmentConfirmationForm, QueueManagementForm,
+# TelemedicineSetupForm, AppointmentRescheduleForm, AppointmentCancellationForm,
+# AppointmentCheckInForm, BulkAppointmentForm
+# )
+# from .flows import AppointmentSchedulingFlow, AppointmentConfirmationFlow, QueueManagementFlow, TelemedicineSetupFlow
+# from patients.models import Patient
+#
+#
+# class AppointmentSchedulingView(LoginRequiredMixin, PermissionRequiredMixin, CreateProcessView):
+# """
+# View for appointment scheduling workflow
+# """
+# model = Appointment
+# form_class = AppointmentSchedulingForm
+# template_name = 'appointments/appointment_scheduling.html'
+# permission_required = 'appointments.can_schedule_appointments'
+# flow_class = AppointmentSchedulingFlow
+#
+# def get_form_kwargs(self):
+# kwargs = super().get_form_kwargs()
+# kwargs['tenant'] = self.request.user.tenant
+# return kwargs
+#
+# def form_valid(self, form):
+# with transaction.atomic():
+# # Create appointment
+# appointment = form.save(commit=False)
+# appointment.tenant = self.request.user.tenant
+# appointment.scheduled_by = self.request.user
+# appointment.status = 'scheduled'
+# appointment.save()
+#
+# # Start appointment scheduling workflow
+# process = self.flow_class.start.run(
+# appointment=appointment,
+# send_confirmation=form.cleaned_data.get('send_confirmation', True),
+# send_reminder=form.cleaned_data.get('send_reminder', True),
+# created_by=self.request.user
+# )
+#
+# messages.success(
+# self.request,
+# f'Appointment scheduled successfully for {appointment.patient.get_full_name()} '
+# f'on {appointment.appointment_date} at {appointment.appointment_time}.'
+# )
+#
+# return redirect('appointments:appointment_detail', pk=appointment.pk)
+#
+# def get_context_data(self, **kwargs):
+# context = super().get_context_data(**kwargs)
+# context['title'] = 'Schedule Appointment'
+# context['breadcrumbs'] = [
+# {'name': 'Home', 'url': reverse('core:dashboard')},
+# {'name': 'Appointments', 'url': reverse('appointments:appointment_list')},
+# {'name': 'Schedule Appointment', 'url': ''}
+# ]
+# context['available_slots'] = self.get_available_slots()
+# return context
+#
+# def get_available_slots(self):
+# """Get available appointment slots for the next 7 days"""
+# slots = []
+# today = timezone.now().date()
+#
+# for i in range(7):
+# date = today + timedelta(days=i)
+# day_slots = self.get_slots_for_date(date)
+# if day_slots:
+# slots.append({
+# 'date': date,
+# 'slots': day_slots
+# })
+#
+# return slots
+#
+# def get_slots_for_date(self, date):
+# """Get available slots for a specific date"""
+# # This would implement slot availability logic
+# return []
+#
+#
+# class AppointmentConfirmationView(LoginRequiredMixin, PermissionRequiredMixin, CreateProcessView):
+# """
+# View for appointment confirmation workflow
+# """
+# model = AppointmentConfirmation
+# form_class = AppointmentConfirmationForm
+# template_name = 'appointments/appointment_confirmation.html'
+# permission_required = 'appointments.can_confirm_appointments'
+# flow_class = AppointmentConfirmationFlow
+#
+# def get_form_kwargs(self):
+# kwargs = super().get_form_kwargs()
+# kwargs['appointment'] = get_object_or_404(Appointment, pk=self.kwargs['appointment_id'])
+# return kwargs
+#
+# def form_valid(self, form):
+# appointment = get_object_or_404(Appointment, pk=self.kwargs['appointment_id'])
+#
+# with transaction.atomic():
+# # Create confirmation record
+# confirmation = form.save(commit=False)
+# confirmation.appointment = appointment
+# confirmation.confirmed_by = self.request.user
+# confirmation.confirmed_at = timezone.now()
+# confirmation.save()
+#
+# # Update appointment status
+# if form.cleaned_data.get('reschedule_requested'):
+# appointment.status = 'reschedule_requested'
+# appointment.save()
+#
+# # Start rescheduling process
+# messages.info(
+# self.request,
+# 'Patient requested reschedule. Please process the reschedule request.'
+# )
+# return redirect('appointments:appointment_reschedule', pk=appointment.pk)
+# else:
+# appointment.status = 'confirmed'
+# appointment.save()
+#
+# # Start confirmation workflow
+# process = self.flow_class.start.run(
+# appointment=appointment,
+# confirmation=confirmation,
+# created_by=self.request.user
+# )
+#
+# messages.success(
+# self.request,
+# f'Appointment confirmed for {appointment.patient.get_full_name()}.'
+# )
+#
+# return redirect('appointments:appointment_detail', pk=appointment.pk)
+#
+# def get_context_data(self, **kwargs):
+# context = super().get_context_data(**kwargs)
+# context['appointment'] = get_object_or_404(Appointment, pk=self.kwargs['appointment_id'])
+# context['title'] = 'Confirm Appointment'
+# return context
+#
+#
+# class QueueManagementView(LoginRequiredMixin, PermissionRequiredMixin, CreateProcessView):
+# """
+# View for queue management workflow
+# """
+# model = Queue
+# form_class = QueueManagementForm
+# template_name = 'appointments/queue_management.html'
+# permission_required = 'appointments.can_manage_queue'
+# flow_class = QueueManagementFlow
+#
+# def form_valid(self, form):
+# appointment = get_object_or_404(Appointment, pk=self.kwargs['appointment_id'])
+#
+# with transaction.atomic():
+# # Create or update queue entry
+# queue_entry, created = Queue.objects.get_or_create(
+# appointment=appointment,
+# defaults={
+# 'tenant': self.request.user.tenant,
+# 'patient': appointment.patient,
+# 'provider': appointment.provider,
+# 'department': appointment.department,
+# 'created_by': self.request.user
+# }
+# )
+#
+# # Update queue entry with form data
+# for field in form.cleaned_data:
+# if hasattr(queue_entry, field):
+# setattr(queue_entry, field, form.cleaned_data[field])
+#
+# queue_entry.save()
+#
+# # Start queue management workflow
+# process = self.flow_class.start.run(
+# queue_entry=queue_entry,
+# appointment=appointment,
+# notify_patient=form.cleaned_data.get('notify_patient', True),
+# created_by=self.request.user
+# )
+#
+# messages.success(
+# self.request,
+# f'Queue updated for {appointment.patient.get_full_name()}. '
+# f'Position: {queue_entry.position}, Wait time: {queue_entry.estimated_wait_time} minutes.'
+# )
+#
+# return redirect('appointments:queue_list')
+#
+# def get_context_data(self, **kwargs):
+# context = super().get_context_data(**kwargs)
+# context['appointment'] = get_object_or_404(Appointment, pk=self.kwargs['appointment_id'])
+# context['title'] = 'Manage Queue'
+# context['current_queue'] = self.get_current_queue()
+# return context
+#
+# def get_current_queue(self):
+# """Get current queue status"""
+# return Queue.objects.filter(
+# tenant=self.request.user.tenant,
+# status='waiting'
+# ).order_by('priority', 'created_at')
+#
+#
+# class TelemedicineSetupView(LoginRequiredMixin, PermissionRequiredMixin, CreateProcessView):
+# """
+# View for telemedicine setup workflow
+# """
+# model = TelemedicineSession
+# form_class = TelemedicineSetupForm
+# template_name = 'appointments/telemedicine_setup.html'
+# permission_required = 'appointments.can_setup_telemedicine'
+# flow_class = TelemedicineSetupFlow
+#
+# def get_form_kwargs(self):
+# kwargs = super().get_form_kwargs()
+# kwargs['appointment'] = get_object_or_404(Appointment, pk=self.kwargs['appointment_id'])
+# return kwargs
+#
+# def form_valid(self, form):
+# appointment = get_object_or_404(Appointment, pk=self.kwargs['appointment_id'])
+#
+# with transaction.atomic():
+# # Create telemedicine session
+# session = form.save(commit=False)
+# session.appointment = appointment
+# session.tenant = self.request.user.tenant
+# session.created_by = self.request.user
+# session.save()
+#
+# # Update appointment type
+# appointment.appointment_type = 'telemedicine'
+# appointment.save()
+#
+# # Start telemedicine setup workflow
+# process = self.flow_class.start.run(
+# session=session,
+# appointment=appointment,
+# test_connection=form.cleaned_data.get('test_connection', True),
+# send_instructions=form.cleaned_data.get('send_instructions', True),
+# created_by=self.request.user
+# )
+#
+# messages.success(
+# self.request,
+# f'Telemedicine session setup completed for {appointment.patient.get_full_name()}. '
+# f'Meeting details have been sent to the patient.'
+# )
+#
+# return redirect('appointments:appointment_detail', pk=appointment.pk)
+#
+# def get_context_data(self, **kwargs):
+# context = super().get_context_data(**kwargs)
+# context['appointment'] = get_object_or_404(Appointment, pk=self.kwargs['appointment_id'])
+# context['title'] = 'Setup Telemedicine'
+# return context
+#
+#
+# class AppointmentRescheduleView(LoginRequiredMixin, PermissionRequiredMixin, FormView):
+# """
+# View for appointment rescheduling
+# """
+# form_class = AppointmentRescheduleForm
+# template_name = 'appointments/appointment_reschedule.html'
+# permission_required = 'appointments.can_reschedule_appointments'
+#
+# def get_success_url(self):
+# return reverse('appointments:appointment_detail', kwargs={'pk': self.kwargs['pk']})
+#
+# def get_form_kwargs(self):
+# kwargs = super().get_form_kwargs()
+# kwargs['tenant'] = self.request.user.tenant
+# kwargs['appointment'] = get_object_or_404(Appointment, pk=self.kwargs['pk'])
+# return kwargs
+#
+# def form_valid(self, form):
+# appointment = get_object_or_404(Appointment, pk=self.kwargs['pk'])
+#
+# with transaction.atomic():
+# # Store original appointment details
+# original_date = appointment.appointment_date
+# original_time = appointment.appointment_time
+# original_provider = appointment.provider
+#
+# # Update appointment
+# appointment.appointment_date = form.cleaned_data['new_date']
+# appointment.appointment_time = form.cleaned_data['new_time']
+# if form.cleaned_data.get('new_provider'):
+# appointment.provider = form.cleaned_data['new_provider']
+# appointment.status = 'rescheduled'
+# appointment.save()
+#
+# # Log reschedule
+# self.log_reschedule(appointment, original_date, original_time, original_provider, form.cleaned_data)
+#
+# # Send notifications
+# if form.cleaned_data.get('notify_patient'):
+# self.send_reschedule_notification(appointment, form.cleaned_data)
+#
+# messages.success(
+# self.request,
+# f'Appointment rescheduled successfully. New date: {appointment.appointment_date}, '
+# f'New time: {appointment.appointment_time}.'
+# )
+#
+# return super().form_valid(form)
+#
+# def log_reschedule(self, appointment, original_date, original_time, original_provider, form_data):
+# """Log reschedule details"""
+# from core.models import AuditLogEntry
+# AuditLogEntry.objects.create(
+# tenant=appointment.tenant,
+# user=self.request.user,
+# event_type='APPOINTMENT_RESCHEDULE',
+# action='UPDATE',
+# object_type='Appointment',
+# object_id=str(appointment.id),
+# details={
+# 'original_date': original_date.isoformat(),
+# 'original_time': original_time.isoformat(),
+# 'original_provider': original_provider.get_full_name() if original_provider else None,
+# 'new_date': form_data['new_date'].isoformat(),
+# 'new_time': form_data['new_time'].isoformat(),
+# 'new_provider': form_data['new_provider'].get_full_name() if form_data.get('new_provider') else None,
+# 'reason': form_data['reschedule_reason'],
+# 'notes': form_data.get('notes', '')
+# },
+# ip_address=self.request.META.get('REMOTE_ADDR'),
+# user_agent=self.request.META.get('HTTP_USER_AGENT', '')
+# )
+#
+# def send_reschedule_notification(self, appointment, form_data):
+# """Send reschedule notification to patient"""
+# if appointment.patient.email:
+# send_mail(
+# subject='Appointment Rescheduled',
+# message=f'Your appointment has been rescheduled to {appointment.appointment_date} at {appointment.appointment_time}.',
+# from_email=settings.DEFAULT_FROM_EMAIL,
+# recipient_list=[appointment.patient.email],
+# fail_silently=True
+# )
+#
+# def get_context_data(self, **kwargs):
+# context = super().get_context_data(**kwargs)
+# context['appointment'] = get_object_or_404(Appointment, pk=self.kwargs['pk'])
+# context['title'] = 'Reschedule Appointment'
+# return context
+#
+#
+# class AppointmentCancellationView(LoginRequiredMixin, PermissionRequiredMixin, FormView):
+# """
+# View for appointment cancellation
+# """
+# form_class = AppointmentCancellationForm
+# template_name = 'appointments/appointment_cancellation.html'
+# permission_required = 'appointments.can_cancel_appointments'
+#
+# def get_success_url(self):
+# return reverse('appointments:appointment_list')
+#
+# def form_valid(self, form):
+# appointment = get_object_or_404(Appointment, pk=self.kwargs['pk'])
+#
+# with transaction.atomic():
+# # Update appointment status
+# appointment.status = 'cancelled'
+# appointment.cancelled_at = timezone.now()
+# appointment.cancelled_by = self.request.user
+# appointment.cancellation_reason = form.cleaned_data['cancellation_reason']
+# appointment.cancellation_notes = form.cleaned_data.get('cancellation_notes', '')
+# appointment.save()
+#
+# # Handle follow-up actions
+# if form.cleaned_data.get('offer_reschedule'):
+# self.offer_reschedule(appointment)
+#
+# if form.cleaned_data.get('notify_patient'):
+# self.send_cancellation_notification(appointment, form.cleaned_data)
+#
+# if form.cleaned_data.get('refund_required'):
+# self.process_refund(appointment)
+#
+# messages.success(
+# self.request,
+# f'Appointment cancelled for {appointment.patient.get_full_name()}.'
+# )
+#
+# return super().form_valid(form)
+#
+# def offer_reschedule(self, appointment):
+# """Offer reschedule options to patient"""
+# # This would implement reschedule offering logic
+# pass
+#
+# def send_cancellation_notification(self, appointment, form_data):
+# """Send cancellation notification to patient"""
+# if appointment.patient.email:
+# send_mail(
+# subject='Appointment Cancelled',
+# message=f'Your appointment on {appointment.appointment_date} has been cancelled. Reason: {form_data["cancellation_reason"]}',
+# from_email=settings.DEFAULT_FROM_EMAIL,
+# recipient_list=[appointment.patient.email],
+# fail_silently=True
+# )
+#
+# def process_refund(self, appointment):
+# """Process refund if required"""
+# # This would implement refund processing logic
+# pass
+#
+# def get_context_data(self, **kwargs):
+# context = super().get_context_data(**kwargs)
+# context['appointment'] = get_object_or_404(Appointment, pk=self.kwargs['pk'])
+# context['title'] = 'Cancel Appointment'
+# return context
+#
+#
+# class AppointmentCheckInView(LoginRequiredMixin, PermissionRequiredMixin, FormView):
+# """
+# View for appointment check-in
+# """
+# form_class = AppointmentCheckInForm
+# template_name = 'appointments/appointment_checkin.html'
+# permission_required = 'appointments.can_checkin_patients'
+#
+# def get_success_url(self):
+# return reverse('appointments:appointment_detail', kwargs={'pk': self.kwargs['pk']})
+#
+# def form_valid(self, form):
+# appointment = get_object_or_404(Appointment, pk=self.kwargs['pk'])
+#
+# with transaction.atomic():
+# # Update appointment status
+# appointment.status = 'checked_in'
+# appointment.checked_in_at = timezone.now()
+# appointment.checked_in_by = self.request.user
+# appointment.arrival_time = form.cleaned_data['arrival_time']
+# appointment.save()
+#
+# # Create queue entry if needed
+# if not hasattr(appointment, 'queue_entry'):
+# Queue.objects.create(
+# appointment=appointment,
+# tenant=appointment.tenant,
+# patient=appointment.patient,
+# provider=appointment.provider,
+# department=appointment.department,
+# queue_type='check_in',
+# priority='normal',
+# status='waiting',
+# created_by=self.request.user
+# )
+#
+# # Handle pre-visit tasks
+# self.process_checkin_tasks(appointment, form.cleaned_data)
+#
+# messages.success(
+# self.request,
+# f'{appointment.patient.get_full_name()} checked in successfully.'
+# )
+#
+# return super().form_valid(form)
+#
+# def process_checkin_tasks(self, appointment, form_data):
+# """Process check-in tasks"""
+# tasks = []
+#
+# if form_data.get('insurance_verified'):
+# tasks.append('Insurance verified')
+# if form_data.get('copay_collected'):
+# tasks.append('Copay collected')
+# if form_data.get('forms_completed'):
+# tasks.append('Forms completed')
+# if form_data.get('vitals_required'):
+# tasks.append('Vitals required')
+#
+# # Log completed tasks
+# if tasks:
+# from core.models import AuditLogEntry
+# AuditLogEntry.objects.create(
+# tenant=appointment.tenant,
+# user=self.request.user,
+# event_type='APPOINTMENT_CHECKIN',
+# action='UPDATE',
+# object_type='Appointment',
+# object_id=str(appointment.id),
+# details={
+# 'completed_tasks': tasks,
+# 'special_needs': form_data.get('special_needs', '')
+# },
+# ip_address=self.request.META.get('REMOTE_ADDR'),
+# user_agent=self.request.META.get('HTTP_USER_AGENT', '')
+# )
+#
+# def get_context_data(self, **kwargs):
+# context = super().get_context_data(**kwargs)
+# context['appointment'] = get_object_or_404(Appointment, pk=self.kwargs['pk'])
+# context['title'] = 'Check In Patient'
+# return context
+#
+#
+# class BulkAppointmentView(LoginRequiredMixin, PermissionRequiredMixin, FormView):
+# """
+# View for bulk appointment operations
+# """
+# form_class = BulkAppointmentForm
+# template_name = 'appointments/bulk_appointment.html'
+# permission_required = 'appointments.can_bulk_manage_appointments'
+#
+# def get_success_url(self):
+# return reverse('appointments:appointment_list')
+#
+# def form_valid(self, form):
+# appointment_ids = form.cleaned_data['appointment_ids'].split(',')
+# appointments = Appointment.objects.filter(
+# id__in=appointment_ids,
+# tenant=self.request.user.tenant
+# )
+#
+# action = form.cleaned_data['action']
+#
+# with transaction.atomic():
+# if action == 'confirm':
+# self.bulk_confirm(appointments, form.cleaned_data)
+# elif action == 'reschedule':
+# self.bulk_reschedule(appointments, form.cleaned_data)
+# elif action == 'cancel':
+# self.bulk_cancel(appointments, form.cleaned_data)
+# elif action == 'send_reminders':
+# self.bulk_send_reminders(appointments, form.cleaned_data)
+#
+# messages.success(
+# self.request,
+# f'Bulk operation "{action}" completed for {appointments.count()} appointments.'
+# )
+#
+# return super().form_valid(form)
+#
+# def bulk_confirm(self, appointments, form_data):
+# """Bulk confirm appointments"""
+# for appointment in appointments:
+# appointment.status = 'confirmed'
+# appointment.save()
+#
+# if form_data.get('notify_patients'):
+# self.send_confirmation_notification(appointment)
+#
+# def bulk_reschedule(self, appointments, form_data):
+# """Bulk reschedule appointments"""
+# new_date = form_data.get('bulk_date')
+# if new_date:
+# for appointment in appointments:
+# appointment.appointment_date = new_date
+# appointment.status = 'rescheduled'
+# appointment.save()
+#
+# if form_data.get('notify_patients'):
+# self.send_reschedule_notification(appointment, form_data)
+#
+# def bulk_cancel(self, appointments, form_data):
+# """Bulk cancel appointments"""
+# for appointment in appointments:
+# appointment.status = 'cancelled'
+# appointment.cancelled_at = timezone.now()
+# appointment.cancelled_by = self.request.user
+# appointment.cancellation_reason = 'bulk_cancellation'
+# appointment.cancellation_notes = form_data.get('bulk_reason', '')
+# appointment.save()
+#
+# if form_data.get('notify_patients'):
+# self.send_cancellation_notification(appointment, form_data)
+#
+# def bulk_send_reminders(self, appointments, form_data):
+# """Bulk send reminders"""
+# for appointment in appointments:
+# if form_data.get('notify_patients'):
+# self.send_reminder_notification(appointment)
+#
+# def send_confirmation_notification(self, appointment):
+# """Send confirmation notification"""
+# if appointment.patient.email:
+# send_mail(
+# subject='Appointment Confirmed',
+# message=f'Your appointment on {appointment.appointment_date} at {appointment.appointment_time} has been confirmed.',
+# from_email=settings.DEFAULT_FROM_EMAIL,
+# recipient_list=[appointment.patient.email],
+# fail_silently=True
+# )
+#
+# def send_reminder_notification(self, appointment):
+# """Send reminder notification"""
+# if appointment.patient.email:
+# send_mail(
+# subject='Appointment Reminder',
+# message=f'Reminder: You have an appointment on {appointment.appointment_date} at {appointment.appointment_time}.',
+# from_email=settings.DEFAULT_FROM_EMAIL,
+# recipient_list=[appointment.patient.email],
+# fail_silently=True
+# )
+#
+# def get_context_data(self, **kwargs):
+# context = super().get_context_data(**kwargs)
+# context['title'] = 'Bulk Appointment Operations'
+# return context
+#
+#
+# class AppointmentListView(LoginRequiredMixin, PermissionRequiredMixin, ListView):
+# """
+# View for listing appointments
+# """
+# model = Appointment
+# template_name = 'appointments/appointment_list.html'
+# context_object_name = 'appointments'
+# permission_required = 'appointments.view_appointment'
+# paginate_by = 25
+#
+# def get_queryset(self):
+# queryset = Appointment.objects.filter(tenant=self.request.user.tenant)
+#
+# # Apply filters
+# search = self.request.GET.get('search')
+# if search:
+# queryset = queryset.filter(
+# Q(patient__first_name__icontains=search) |
+# Q(patient__last_name__icontains=search) |
+# Q(provider__first_name__icontains=search) |
+# Q(provider__last_name__icontains=search) |
+# Q(reason__icontains=search)
+# )
+#
+# status = self.request.GET.get('status')
+# if status:
+# queryset = queryset.filter(status=status)
+#
+# date_from = self.request.GET.get('date_from')
+# if date_from:
+# queryset = queryset.filter(appointment_date__gte=date_from)
+#
+# date_to = self.request.GET.get('date_to')
+# if date_to:
+# queryset = queryset.filter(appointment_date__lte=date_to)
+#
+# provider = self.request.GET.get('provider')
+# if provider:
+# queryset = queryset.filter(provider_id=provider)
+#
+# return queryset.order_by('appointment_date', 'appointment_time')
+#
+# def get_context_data(self, **kwargs):
+# context = super().get_context_data(**kwargs)
+# context['title'] = 'Appointments'
+# context['providers'] = self.get_providers()
+# context['search'] = self.request.GET.get('search', '')
+# context['selected_status'] = self.request.GET.get('status', '')
+# context['selected_provider'] = self.request.GET.get('provider', '')
+# context['date_from'] = self.request.GET.get('date_from', '')
+# context['date_to'] = self.request.GET.get('date_to', '')
+# return context
+#
+# def get_providers(self):
+# """Get providers for filter"""
+# from django.contrib.auth.models import User
+# return User.objects.filter(
+# tenant=self.request.user.tenant,
+# groups__name__in=['Doctors', 'Nurses', 'Specialists']
+# ).distinct()
+#
+#
+# class AppointmentDetailView(LoginRequiredMixin, PermissionRequiredMixin, DetailView):
+# """
+# View for appointment details
+# """
+# model = Appointment
+# template_name = 'appointments/appointment_detail.html'
+# context_object_name = 'appointment'
+# permission_required = 'appointments.view_appointment'
+#
+# def get_queryset(self):
+# return Appointment.objects.filter(tenant=self.request.user.tenant)
+#
+# def get_context_data(self, **kwargs):
+# context = super().get_context_data(**kwargs)
+# appointment = self.object
+# context['title'] = f'Appointment - {appointment.patient.get_full_name()}'
+# context['confirmation'] = getattr(appointment, 'confirmation', None)
+# context['queue_entry'] = getattr(appointment, 'queue_entry', None)
+# context['telemedicine_session'] = getattr(appointment, 'telemedicine_session', None)
+# context['can_edit'] = self.request.user.has_perm('appointments.change_appointment')
+# context['can_cancel'] = self.request.user.has_perm('appointments.can_cancel_appointments')
+# context['can_reschedule'] = self.request.user.has_perm('appointments.can_reschedule_appointments')
+# return context
+#
+#
+# class QueueListView(LoginRequiredMixin, PermissionRequiredMixin, ListView):
+# """
+# View for listing queue entries
+# """
+# model = Queue
+# template_name = 'appointments/queue_list.html'
+# context_object_name = 'queue_entries'
+# permission_required = 'appointments.view_queue'
+#
+# def get_queryset(self):
+# queryset = Queue.objects.filter(tenant=self.request.user.tenant)
+#
+# # Apply filters
+# status = self.request.GET.get('status', 'waiting')
+# if status:
+# queryset = queryset.filter(status=status)
+#
+# department = self.request.GET.get('department')
+# if department:
+# queryset = queryset.filter(department_id=department)
+#
+# return queryset.order_by('priority', 'created_at')
+#
+# def get_context_data(self, **kwargs):
+# context = super().get_context_data(**kwargs)
+# context['title'] = 'Patient Queue'
+# context['departments'] = self.get_departments()
+# context['selected_status'] = self.request.GET.get('status', 'waiting')
+# context['selected_department'] = self.request.GET.get('department', '')
+# context['queue_stats'] = self.get_queue_stats()
+# return context
+#
+# def get_departments(self):
+# """Get departments for filter"""
+# from core.models import Department
+# return Department.objects.filter(tenant=self.request.user.tenant)
+#
+# def get_queue_stats(self):
+# """Get queue statistics"""
+# return {
+# 'total_waiting': Queue.objects.filter(
+# tenant=self.request.user.tenant,
+# status='waiting'
+# ).count(),
+# 'average_wait_time': 25, # Would be calculated
+# 'longest_wait': 45 # Would be calculated
+# }
+#
+#
+# # AJAX Views
+# @login_required
+# @permission_required('appointments.view_appointment')
+# def appointment_availability_ajax(request):
+# """AJAX view to check appointment availability"""
+# date = request.GET.get('date')
+# provider_id = request.GET.get('provider_id')
+#
+# if not date or not provider_id:
+# return JsonResponse({'success': False, 'message': 'Missing parameters'})
+#
+# try:
+# from django.contrib.auth.models import User
+# provider = User.objects.get(id=provider_id, tenant=request.user.tenant)
+# appointment_date = datetime.strptime(date, '%Y-%m-%d').date()
+#
+# # Get existing appointments for the date
+# existing_appointments = Appointment.objects.filter(
+# provider=provider,
+# appointment_date=appointment_date,
+# status__in=['scheduled', 'confirmed', 'in_progress']
+# )
+#
+# # Generate available slots
+# available_slots = generate_available_slots(appointment_date, existing_appointments)
+#
+# return JsonResponse({
+# 'success': True,
+# 'slots': available_slots
+# })
+# except Exception as e:
+# return JsonResponse({'success': False, 'message': str(e)})
+#
+#
+# @login_required
+# @permission_required('appointments.view_patient')
+# def patient_search_ajax(request):
+# """AJAX view for patient search"""
+# query = request.GET.get('q', '')
+# if len(query) < 2:
+# return JsonResponse({'patients': []})
+#
+# patients = Patient.objects.filter(
+# tenant=request.user.tenant
+# ).filter(
+# Q(first_name__icontains=query) |
+# Q(last_name__icontains=query) |
+# Q(patient_id__icontains=query) |
+# Q(phone_number__icontains=query)
+# )[:10]
+#
+# patient_data = [
+# {
+# 'id': patient.id,
+# 'name': patient.get_full_name(),
+# 'patient_id': patient.patient_id,
+# 'phone': patient.phone_number,
+# 'email': patient.email
+# }
+# for patient in patients
+# ]
+#
+# return JsonResponse({'patients': patient_data})
+#
+#
+# @login_required
+# @permission_required('appointments.can_manage_queue')
+# def update_queue_position_ajax(request):
+# """AJAX view to update queue position"""
+# if request.method == 'POST':
+# try:
+# data = json.loads(request.body)
+# queue_id = data.get('queue_id')
+# new_position = data.get('new_position')
+#
+# queue_entry = Queue.objects.get(
+# id=queue_id,
+# tenant=request.user.tenant
+# )
+#
+# queue_entry.position = new_position
+# queue_entry.save()
+#
+# return JsonResponse({
+# 'success': True,
+# 'message': 'Queue position updated successfully.'
+# })
+# except Queue.DoesNotExist:
+# return JsonResponse({
+# 'success': False,
+# 'message': 'Queue entry not found.'
+# })
+# except Exception as e:
+# return JsonResponse({
+# 'success': False,
+# 'message': str(e)
+# })
+#
+# return JsonResponse({'success': False, 'message': 'Invalid request.'})
+#
+#
+# def generate_available_slots(date, existing_appointments):
+# """Generate available appointment slots for a date"""
+# slots = []
+# start_time = datetime.strptime('09:00', '%H:%M').time()
+# end_time = datetime.strptime('17:00', '%H:%M').time()
+# slot_duration = 30 # minutes
+#
+# current_time = datetime.combine(date, start_time)
+# end_datetime = datetime.combine(date, end_time)
+#
+# while current_time < end_datetime:
+# slot_time = current_time.time()
+#
+# # Check if slot is available
+# is_available = True
+# for appointment in existing_appointments:
+# appointment_start = datetime.combine(date, appointment.appointment_time)
+# appointment_end = appointment_start + timedelta(minutes=appointment.duration)
+#
+# slot_start = current_time
+# slot_end = current_time + timedelta(minutes=slot_duration)
+#
+# if slot_start < appointment_end and slot_end > appointment_start:
+# is_available = False
+# break
+#
+# if is_available:
+# slots.append({
+# 'time': slot_time.strftime('%H:%M'),
+# 'available': True
+# })
+#
+# current_time += timedelta(minutes=slot_duration)
+#
+# return slots
+#
diff --git a/billing/__pycache__/flows.cpython-312.pyc b/billing/__pycache__/flows.cpython-312.pyc
new file mode 100644
index 00000000..b0341c05
Binary files /dev/null and b/billing/__pycache__/flows.cpython-312.pyc differ
diff --git a/billing/__pycache__/forms.cpython-312.pyc b/billing/__pycache__/forms.cpython-312.pyc
index dee0ae36..1499c47d 100644
Binary files a/billing/__pycache__/forms.cpython-312.pyc and b/billing/__pycache__/forms.cpython-312.pyc differ
diff --git a/billing/__pycache__/urls.cpython-312.pyc b/billing/__pycache__/urls.cpython-312.pyc
index 1100ee35..dd846f07 100644
Binary files a/billing/__pycache__/urls.cpython-312.pyc and b/billing/__pycache__/urls.cpython-312.pyc differ
diff --git a/billing/__pycache__/views.cpython-312.pyc b/billing/__pycache__/views.cpython-312.pyc
index de825d6a..f9e5bcdf 100644
Binary files a/billing/__pycache__/views.cpython-312.pyc and b/billing/__pycache__/views.cpython-312.pyc differ
diff --git a/billing/flows.py b/billing/flows.py
new file mode 100644
index 00000000..3088bc61
--- /dev/null
+++ b/billing/flows.py
@@ -0,0 +1,1022 @@
+# """
+# Viewflow workflows for billing app.
+# Provides medical billing, insurance claims, and payment processing workflows.
+# """
+#
+# from viewflow import Flow, lock
+# from viewflow.base import this, flow_func
+# from viewflow.contrib import celery
+# from viewflow.decorators import flow_view
+# from viewflow.fields import CharField, ModelField
+# from viewflow.forms import ModelForm
+# from viewflow.views import CreateProcessView, UpdateProcessView
+# from viewflow.models import Process, Task
+# from django.contrib.auth.models import User
+# from django.urls import reverse_lazy
+# from django.utils import timezone
+# from django.db import transaction
+# from django.core.mail import send_mail
+#
+# from .models import MedicalBill, InsuranceClaim, Payment, ClaimStatusUpdate
+# from .views import (
+# BillGenerationView, ChargeReviewView, InsuranceVerificationView,
+# ClaimPreparationView, ClaimSubmissionView, ClaimTrackingView,
+# PaymentProcessingView, PaymentReconciliationView, DenialManagementView,
+# AppealPreparationView, CollectionsView
+# )
+#
+#
+# class MedicalBillingProcess(Process):
+# """
+# Viewflow process model for medical billing
+# """
+# medical_bill = ModelField(MedicalBill, help_text='Associated medical bill')
+#
+# # Process status tracking
+# charges_captured = models.BooleanField(default=False)
+# charges_reviewed = models.BooleanField(default=False)
+# insurance_verified = models.BooleanField(default=False)
+# bill_generated = models.BooleanField(default=False)
+# claims_submitted = models.BooleanField(default=False)
+# payments_processed = models.BooleanField(default=False)
+# account_reconciled = models.BooleanField(default=False)
+# billing_completed = models.BooleanField(default=False)
+#
+# class Meta:
+# verbose_name = 'Medical Billing Process'
+# verbose_name_plural = 'Medical Billing Processes'
+#
+#
+# class MedicalBillingFlow(Flow):
+# """
+# Medical Billing Workflow
+#
+# This flow manages the complete revenue cycle from charge capture
+# through payment processing and account reconciliation.
+# """
+#
+# process_class = MedicalBillingProcess
+#
+# # Flow definition
+# start = (
+# flow_func(this.start_billing)
+# .Next(this.capture_charges)
+# )
+#
+# capture_charges = (
+# flow_func(this.collect_service_charges)
+# .Next(this.review_charges)
+# )
+#
+# review_charges = (
+# flow_view(ChargeReviewView)
+# .Permission('billing.can_review_charges')
+# .Next(this.verify_insurance)
+# )
+#
+# verify_insurance = (
+# flow_view(InsuranceVerificationView)
+# .Permission('billing.can_verify_insurance')
+# .Next(this.generate_bill)
+# )
+#
+# generate_bill = (
+# flow_view(BillGenerationView)
+# .Permission('billing.can_generate_bills')
+# .Next(this.parallel_claim_processing)
+# )
+#
+# parallel_claim_processing = (
+# flow_func(this.start_parallel_processing)
+# .Next(this.submit_primary_claim)
+# .Next(this.submit_secondary_claim)
+# .Next(this.patient_billing)
+# )
+#
+# submit_primary_claim = (
+# flow_view(PrimaryClaimSubmissionView)
+# .Permission('billing.can_submit_claims')
+# .Next(this.join_claim_processing)
+# )
+#
+# submit_secondary_claim = (
+# flow_view(SecondaryClaimSubmissionView)
+# .Permission('billing.can_submit_claims')
+# .Next(this.join_claim_processing)
+# )
+#
+# patient_billing = (
+# flow_view(PatientBillingView)
+# .Permission('billing.can_bill_patients')
+# .Next(this.join_claim_processing)
+# )
+#
+# join_claim_processing = (
+# flow_func(this.join_parallel_processing)
+# .Next(this.process_payments)
+# )
+#
+# process_payments = (
+# flow_view(PaymentProcessingView)
+# .Permission('billing.can_process_payments')
+# .Next(this.reconcile_account)
+# )
+#
+# reconcile_account = (
+# flow_view(PaymentReconciliationView)
+# .Permission('billing.can_reconcile_accounts')
+# .Next(this.finalize_billing)
+# )
+#
+# finalize_billing = (
+# flow_func(this.complete_billing)
+# .Next(this.end)
+# )
+#
+# end = flow_func(this.end_billing)
+#
+# # Flow functions
+# def start_billing(self, activation):
+# """Initialize the billing process"""
+# process = activation.process
+# bill = process.medical_bill
+#
+# # Update bill status
+# bill.status = 'PROCESSING'
+# bill.save()
+#
+# # Send notification to billing staff
+# self.notify_billing_staff(bill)
+#
+# # Check for priority billing
+# if bill.bill_type in ['EMERGENCY', 'SURGERY']:
+# self.notify_priority_billing(bill)
+#
+# def collect_service_charges(self, activation):
+# """Collect charges from various service departments"""
+# process = activation.process
+# bill = process.medical_bill
+#
+# # Collect charges from different departments
+# charges = self.gather_service_charges(bill)
+#
+# if charges:
+# # Update bill with collected charges
+# self.update_bill_charges(bill, charges)
+#
+# process.charges_captured = True
+# process.save()
+#
+# def start_parallel_processing(self, activation):
+# """Start parallel claim and billing processing"""
+# process = activation.process
+#
+# # Create parallel processing tasks
+# self.create_claim_tasks(process.medical_bill)
+#
+# def join_parallel_processing(self, activation):
+# """Wait for all claim processing to complete"""
+# process = activation.process
+#
+# # Check if all processing is completed
+# if self.all_claims_processed(process.medical_bill):
+# # Proceed to payment processing
+# self.notify_claims_completed(process.medical_bill)
+#
+# def complete_billing(self, activation):
+# """Finalize the billing process"""
+# process = activation.process
+# bill = process.medical_bill
+#
+# # Update bill status based on payment status
+# if bill.balance_due <= 0:
+# bill.status = 'PAID'
+# elif bill.total_payments > 0:
+# bill.status = 'PARTIALLY_PAID'
+# else:
+# bill.status = 'OUTSTANDING'
+#
+# bill.save()
+#
+# # Mark process as completed
+# process.billing_completed = True
+# process.save()
+#
+# # Send completion notifications
+# self.notify_billing_completion(bill)
+#
+# # Update revenue metrics
+# self.update_revenue_metrics(bill)
+#
+# def end_billing(self, activation):
+# """End the billing workflow"""
+# process = activation.process
+#
+# # Generate billing summary report
+# self.generate_billing_summary(process.medical_bill)
+#
+# # Helper methods
+# def notify_billing_staff(self, bill):
+# """Notify billing staff of new bill"""
+# from django.contrib.auth.models import Group
+#
+# billing_staff = User.objects.filter(
+# groups__name='Billing Staff'
+# )
+#
+# for staff in billing_staff:
+# send_mail(
+# subject=f'New Medical Bill: {bill.bill_number}',
+# message=f'New medical bill for {bill.patient.get_full_name()} requires processing.',
+# from_email='billing@hospital.com',
+# recipient_list=[staff.email],
+# fail_silently=True
+# )
+#
+# def notify_priority_billing(self, bill):
+# """Notify of priority billing"""
+# billing_managers = User.objects.filter(
+# groups__name='Billing Managers'
+# )
+#
+# for manager in billing_managers:
+# send_mail(
+# subject=f'PRIORITY Billing: {bill.bill_number}',
+# message=f'{bill.get_bill_type_display()} bill requires priority processing.',
+# from_email='billing@hospital.com',
+# recipient_list=[manager.email],
+# fail_silently=True
+# )
+#
+# def gather_service_charges(self, bill):
+# """Gather charges from service departments"""
+# # This would collect charges from various departments
+# return []
+#
+# def update_bill_charges(self, bill, charges):
+# """Update bill with collected charges"""
+# # This would update the bill with charges
+# pass
+#
+# def create_claim_tasks(self, bill):
+# """Create claim processing tasks"""
+# # This would create tasks for claim processing
+# pass
+#
+# def all_claims_processed(self, bill):
+# """Check if all claims are processed"""
+# # This would check claim processing status
+# return True
+#
+# def notify_claims_completed(self, bill):
+# """Notify that claims processing is completed"""
+# billing_staff = User.objects.filter(
+# groups__name='Billing Staff'
+# )
+#
+# for staff in billing_staff:
+# send_mail(
+# subject=f'Claims Processed: {bill.bill_number}',
+# message=f'All claims have been processed for {bill.patient.get_full_name()}.',
+# from_email='billing@hospital.com',
+# recipient_list=[staff.email],
+# fail_silently=True
+# )
+#
+# def notify_billing_completion(self, bill):
+# """Notify billing completion"""
+# # Notify patient if email available
+# if bill.patient.email:
+# send_mail(
+# subject='Medical Bill Processed',
+# message=f'Your medical bill {bill.bill_number} has been processed.',
+# from_email='billing@hospital.com',
+# recipient_list=[bill.patient.email],
+# fail_silently=True
+# )
+#
+# def update_revenue_metrics(self, bill):
+# """Update revenue cycle metrics"""
+# # This would update revenue metrics
+# pass
+#
+# def generate_billing_summary(self, bill):
+# """Generate billing summary report"""
+# # This would generate a comprehensive billing report
+# pass
+#
+#
+# class InsuranceClaimProcess(Process):
+# """
+# Viewflow process model for insurance claims
+# """
+# insurance_claim = ModelField(InsuranceClaim, help_text='Associated insurance claim')
+#
+# # Process status tracking
+# claim_prepared = models.BooleanField(default=False)
+# eligibility_verified = models.BooleanField(default=False)
+# claim_submitted = models.BooleanField(default=False)
+# claim_tracked = models.BooleanField(default=False)
+# response_received = models.BooleanField(default=False)
+# payment_posted = models.BooleanField(default=False)
+# denials_managed = models.BooleanField(default=False)
+# claim_finalized = models.BooleanField(default=False)
+#
+# class Meta:
+# verbose_name = 'Insurance Claim Process'
+# verbose_name_plural = 'Insurance Claim Processes'
+#
+#
+# class InsuranceClaimFlow(Flow):
+# """
+# Insurance Claim Processing Workflow
+#
+# This flow manages insurance claim processing from preparation
+# through payment posting and denial management.
+# """
+#
+# process_class = InsuranceClaimProcess
+#
+# # Flow definition
+# start = (
+# flow_func(this.start_claim)
+# .Next(this.prepare_claim)
+# )
+#
+# prepare_claim = (
+# flow_view(ClaimPreparationView)
+# .Permission('billing.can_prepare_claims')
+# .Next(this.verify_eligibility)
+# )
+#
+# verify_eligibility = (
+# flow_view(EligibilityVerificationView)
+# .Permission('billing.can_verify_eligibility')
+# .Next(this.submit_claim)
+# )
+#
+# submit_claim = (
+# flow_view(ClaimSubmissionView)
+# .Permission('billing.can_submit_claims')
+# .Next(this.track_claim)
+# )
+#
+# track_claim = (
+# flow_view(ClaimTrackingView)
+# .Permission('billing.can_track_claims')
+# .Next(this.receive_response)
+# )
+#
+# receive_response = (
+# flow_func(this.process_claim_response)
+# .Next(this.post_payment)
+# )
+#
+# post_payment = (
+# flow_view(PaymentPostingView)
+# .Permission('billing.can_post_payments')
+# .Next(this.manage_denials)
+# )
+#
+# manage_denials = (
+# flow_view(DenialManagementView)
+# .Permission('billing.can_manage_denials')
+# .Next(this.finalize_claim)
+# )
+#
+# finalize_claim = (
+# flow_func(this.complete_claim)
+# .Next(this.end)
+# )
+#
+# end = flow_func(this.end_claim)
+#
+# # Flow functions
+# def start_claim(self, activation):
+# """Initialize the claim process"""
+# process = activation.process
+# claim = process.insurance_claim
+#
+# # Update claim status
+# claim.status = 'PREPARING'
+# claim.save()
+#
+# # Send notification to claims staff
+# self.notify_claims_staff(claim)
+#
+# def process_claim_response(self, activation):
+# """Process insurance claim response"""
+# process = activation.process
+# claim = process.insurance_claim
+#
+# # Check for claim response
+# response = self.check_claim_response(claim)
+#
+# if response:
+# # Update claim with response
+# self.update_claim_response(claim, response)
+#
+# process.response_received = True
+# process.save()
+#
+# # Handle different response types
+# if response.get('status') == 'DENIED':
+# self.handle_claim_denial(claim, response)
+# elif response.get('status') == 'PAID':
+# self.handle_claim_payment(claim, response)
+#
+# def complete_claim(self, activation):
+# """Finalize the claim process"""
+# process = activation.process
+# claim = process.insurance_claim
+#
+# # Update claim status based on final outcome
+# if claim.paid_amount >= claim.billed_amount:
+# claim.status = 'PAID'
+# elif claim.paid_amount > 0:
+# claim.status = 'PARTIALLY_PAID'
+# elif claim.denial_reason:
+# claim.status = 'DENIED'
+# else:
+# claim.status = 'PENDING'
+#
+# claim.save()
+#
+# # Mark process as completed
+# process.claim_finalized = True
+# process.save()
+#
+# # Send completion notifications
+# self.notify_claim_completion(claim)
+#
+# def end_claim(self, activation):
+# """End the claim workflow"""
+# process = activation.process
+#
+# # Generate claim summary report
+# self.generate_claim_summary(process.insurance_claim)
+#
+# # Helper methods
+# def notify_claims_staff(self, claim):
+# """Notify claims staff"""
+# claims_staff = User.objects.filter(
+# groups__name='Claims Staff'
+# )
+#
+# for staff in claims_staff:
+# send_mail(
+# subject=f'New Insurance Claim: {claim.claim_number}',
+# message=f'New insurance claim for {claim.patient.get_full_name()} requires processing.',
+# from_email='claims@hospital.com',
+# recipient_list=[staff.email],
+# fail_silently=True
+# )
+#
+# def check_claim_response(self, claim):
+# """Check for claim response from insurance"""
+# # This would check for insurance responses
+# return None
+#
+# def update_claim_response(self, claim, response):
+# """Update claim with insurance response"""
+# # This would update the claim with response data
+# pass
+#
+# def handle_claim_denial(self, claim, response):
+# """Handle claim denial"""
+# # Notify claims staff of denial
+# claims_staff = User.objects.filter(
+# groups__name='Claims Staff'
+# )
+#
+# for staff in claims_staff:
+# send_mail(
+# subject=f'Claim Denied: {claim.claim_number}',
+# message=f'Insurance claim has been denied. Reason: {response.get("denial_reason", "Unknown")}',
+# from_email='claims@hospital.com',
+# recipient_list=[staff.email],
+# fail_silently=True
+# )
+#
+# def handle_claim_payment(self, claim, response):
+# """Handle claim payment"""
+# # This would process claim payment
+# pass
+#
+# def notify_claim_completion(self, claim):
+# """Notify claim completion"""
+# # This would notify relevant parties
+# pass
+#
+# def generate_claim_summary(self, claim):
+# """Generate claim summary report"""
+# # This would generate claim summary
+# pass
+#
+#
+# class PaymentProcessingProcess(Process):
+# """
+# Viewflow process model for payment processing
+# """
+# payment = ModelField(Payment, help_text='Associated payment')
+#
+# # Process status tracking
+# payment_received = models.BooleanField(default=False)
+# payment_verified = models.BooleanField(default=False)
+# payment_processed = models.BooleanField(default=False)
+# payment_deposited = models.BooleanField(default=False)
+# account_updated = models.BooleanField(default=False)
+# receipt_generated = models.BooleanField(default=False)
+# payment_completed = models.BooleanField(default=False)
+#
+# class Meta:
+# verbose_name = 'Payment Processing Process'
+# verbose_name_plural = 'Payment Processing Processes'
+#
+#
+# class PaymentProcessingFlow(Flow):
+# """
+# Payment Processing Workflow
+#
+# This flow manages payment processing from receipt through
+# deposit and account reconciliation.
+# """
+#
+# process_class = PaymentProcessingProcess
+#
+# # Flow definition
+# start = (
+# flow_func(this.start_payment)
+# .Next(this.receive_payment)
+# )
+#
+# receive_payment = (
+# flow_view(PaymentReceiptView)
+# .Permission('billing.can_receive_payments')
+# .Next(this.verify_payment)
+# )
+#
+# verify_payment = (
+# flow_view(PaymentVerificationView)
+# .Permission('billing.can_verify_payments')
+# .Next(this.process_payment)
+# )
+#
+# process_payment = (
+# flow_view(PaymentProcessingView)
+# .Permission('billing.can_process_payments')
+# .Next(this.deposit_payment)
+# )
+#
+# deposit_payment = (
+# flow_view(PaymentDepositView)
+# .Permission('billing.can_deposit_payments')
+# .Next(this.update_account)
+# )
+#
+# update_account = (
+# flow_func(this.update_patient_account)
+# .Next(this.generate_receipt)
+# )
+#
+# generate_receipt = (
+# flow_view(ReceiptGenerationView)
+# .Permission('billing.can_generate_receipts')
+# .Next(this.finalize_payment)
+# )
+#
+# finalize_payment = (
+# flow_func(this.complete_payment)
+# .Next(this.end)
+# )
+#
+# end = flow_func(this.end_payment)
+#
+# # Flow functions
+# def start_payment(self, activation):
+# """Initialize the payment process"""
+# process = activation.process
+# payment = process.payment
+#
+# # Update payment status
+# payment.status = 'PENDING'
+# payment.save()
+#
+# # Send notification to billing staff
+# self.notify_payment_received(payment)
+#
+# def update_patient_account(self, activation):
+# """Update patient account with payment"""
+# process = activation.process
+# payment = process.payment
+#
+# # Update medical bill balance
+# bill = payment.medical_bill
+# bill.total_payments += payment.payment_amount
+# bill.balance_due = bill.total_amount - bill.total_payments
+# bill.save()
+#
+# process.account_updated = True
+# process.save()
+#
+# # Check if bill is fully paid
+# if bill.balance_due <= 0:
+# self.notify_account_paid_in_full(bill)
+#
+# def complete_payment(self, activation):
+# """Finalize the payment process"""
+# process = activation.process
+# payment = process.payment
+#
+# # Update payment status
+# payment.status = 'PROCESSED'
+# payment.save()
+#
+# # Mark process as completed
+# process.payment_completed = True
+# process.save()
+#
+# # Send completion notifications
+# self.notify_payment_completion(payment)
+#
+# def end_payment(self, activation):
+# """End the payment workflow"""
+# process = activation.process
+#
+# # Generate payment summary report
+# self.generate_payment_summary(process.payment)
+#
+# # Helper methods
+# def notify_payment_received(self, payment):
+# """Notify billing staff of payment received"""
+# billing_staff = User.objects.filter(
+# groups__name='Billing Staff'
+# )
+#
+# for staff in billing_staff:
+# send_mail(
+# subject=f'Payment Received: {payment.payment_number}',
+# message=f'Payment of ${payment.payment_amount} received for {payment.patient.get_full_name()}.',
+# from_email='billing@hospital.com',
+# recipient_list=[staff.email],
+# fail_silently=True
+# )
+#
+# def notify_account_paid_in_full(self, bill):
+# """Notify that account is paid in full"""
+# # Notify patient
+# if bill.patient.email:
+# send_mail(
+# subject='Account Paid in Full',
+# message=f'Your account for bill {bill.bill_number} has been paid in full.',
+# from_email='billing@hospital.com',
+# recipient_list=[bill.patient.email],
+# fail_silently=True
+# )
+#
+# def notify_payment_completion(self, payment):
+# """Notify payment completion"""
+# # This would notify relevant parties
+# pass
+#
+# def generate_payment_summary(self, payment):
+# """Generate payment summary report"""
+# # This would generate payment summary
+# pass
+#
+#
+# class DenialManagementProcess(Process):
+# """
+# Viewflow process model for denial management
+# """
+# insurance_claim = ModelField(InsuranceClaim, help_text='Associated denied claim')
+#
+# # Process status tracking
+# denial_analyzed = models.BooleanField(default=False)
+# appeal_prepared = models.BooleanField(default=False)
+# appeal_submitted = models.BooleanField(default=False)
+# appeal_tracked = models.BooleanField(default=False)
+# appeal_resolved = models.BooleanField(default=False)
+# account_adjusted = models.BooleanField(default=False)
+# denial_completed = models.BooleanField(default=False)
+#
+# class Meta:
+# verbose_name = 'Denial Management Process'
+# verbose_name_plural = 'Denial Management Processes'
+#
+#
+# class DenialManagementFlow(Flow):
+# """
+# Denial Management Workflow
+#
+# This flow manages insurance claim denials including analysis,
+# appeal preparation, submission, and resolution.
+# """
+#
+# process_class = DenialManagementProcess
+#
+# # Flow definition
+# start = (
+# flow_func(this.start_denial_management)
+# .Next(this.analyze_denial)
+# )
+#
+# analyze_denial = (
+# flow_view(DenialAnalysisView)
+# .Permission('billing.can_analyze_denials')
+# .Next(this.prepare_appeal)
+# )
+#
+# prepare_appeal = (
+# flow_view(AppealPreparationView)
+# .Permission('billing.can_prepare_appeals')
+# .Next(this.submit_appeal)
+# )
+#
+# submit_appeal = (
+# flow_view(AppealSubmissionView)
+# .Permission('billing.can_submit_appeals')
+# .Next(this.track_appeal)
+# )
+#
+# track_appeal = (
+# flow_view(AppealTrackingView)
+# .Permission('billing.can_track_appeals')
+# .Next(this.resolve_appeal)
+# )
+#
+# resolve_appeal = (
+# flow_func(this.process_appeal_resolution)
+# .Next(this.adjust_account)
+# )
+#
+# adjust_account = (
+# flow_view(AccountAdjustmentView)
+# .Permission('billing.can_adjust_accounts')
+# .Next(this.finalize_denial)
+# )
+#
+# finalize_denial = (
+# flow_func(this.complete_denial_management)
+# .Next(this.end)
+# )
+#
+# end = flow_func(this.end_denial_management)
+#
+# # Flow functions
+# def start_denial_management(self, activation):
+# """Initialize the denial management process"""
+# process = activation.process
+# claim = process.insurance_claim
+#
+# # Send notification to denial management staff
+# self.notify_denial_staff(claim)
+#
+# def process_appeal_resolution(self, activation):
+# """Process appeal resolution"""
+# process = activation.process
+# claim = process.insurance_claim
+#
+# # Check appeal status
+# appeal_result = self.check_appeal_status(claim)
+#
+# if appeal_result:
+# # Update claim with appeal result
+# self.update_appeal_result(claim, appeal_result)
+#
+# process.appeal_resolved = True
+# process.save()
+#
+# def complete_denial_management(self, activation):
+# """Finalize the denial management process"""
+# process = activation.process
+# claim = process.insurance_claim
+#
+# # Mark process as completed
+# process.denial_completed = True
+# process.save()
+#
+# # Send completion notifications
+# self.notify_denial_completion(claim)
+#
+# def end_denial_management(self, activation):
+# """End the denial management workflow"""
+# process = activation.process
+#
+# # Generate denial management summary
+# self.generate_denial_summary(process.insurance_claim)
+#
+# # Helper methods
+# def notify_denial_staff(self, claim):
+# """Notify denial management staff"""
+# denial_staff = User.objects.filter(
+# groups__name='Denial Management'
+# )
+#
+# for staff in denial_staff:
+# send_mail(
+# subject=f'Claim Denial: {claim.claim_number}',
+# message=f'Insurance claim has been denied and requires review.',
+# from_email='denials@hospital.com',
+# recipient_list=[staff.email],
+# fail_silently=True
+# )
+#
+# def check_appeal_status(self, claim):
+# """Check appeal status"""
+# # This would check appeal status
+# return None
+#
+# def update_appeal_result(self, claim, result):
+# """Update claim with appeal result"""
+# # This would update the claim with appeal result
+# pass
+#
+# def notify_denial_completion(self, claim):
+# """Notify denial management completion"""
+# # This would notify relevant parties
+# pass
+#
+# def generate_denial_summary(self, claim):
+# """Generate denial management summary"""
+# # This would generate denial summary
+# pass
+#
+#
+# class CollectionsProcess(Process):
+# """
+# Viewflow process model for collections
+# """
+# medical_bill = ModelField(MedicalBill, help_text='Associated medical bill')
+#
+# # Process status tracking
+# account_reviewed = models.BooleanField(default=False)
+# patient_contacted = models.BooleanField(default=False)
+# payment_plan_offered = models.BooleanField(default=False)
+# collection_actions_taken = models.BooleanField(default=False)
+# external_agency_assigned = models.BooleanField(default=False)
+# collections_resolved = models.BooleanField(default=False)
+#
+# class Meta:
+# verbose_name = 'Collections Process'
+# verbose_name_plural = 'Collections Processes'
+#
+#
+# class CollectionsFlow(Flow):
+# """
+# Collections Workflow
+#
+# This flow manages collections activities for overdue accounts
+# including patient contact, payment plans, and external collections.
+# """
+#
+# process_class = CollectionsProcess
+#
+# # Flow definition
+# start = (
+# flow_func(this.start_collections)
+# .Next(this.review_account)
+# )
+#
+# review_account = (
+# flow_view(AccountReviewView)
+# .Permission('billing.can_review_collections')
+# .Next(this.contact_patient)
+# )
+#
+# contact_patient = (
+# flow_view(PatientContactView)
+# .Permission('billing.can_contact_patients')
+# .Next(this.offer_payment_plan)
+# )
+#
+# offer_payment_plan = (
+# flow_view(PaymentPlanView)
+# .Permission('billing.can_offer_payment_plans')
+# .Next(this.collection_actions)
+# )
+#
+# collection_actions = (
+# flow_view(CollectionActionsView)
+# .Permission('billing.can_take_collection_actions')
+# .Next(this.external_collections)
+# )
+#
+# external_collections = (
+# flow_view(ExternalCollectionsView)
+# .Permission('billing.can_assign_external_collections')
+# .Next(this.resolve_collections)
+# )
+#
+# resolve_collections = (
+# flow_func(this.complete_collections)
+# .Next(this.end)
+# )
+#
+# end = flow_func(this.end_collections)
+#
+# # Flow functions
+# def start_collections(self, activation):
+# """Initialize the collections process"""
+# process = activation.process
+# bill = process.medical_bill
+#
+# # Send notification to collections staff
+# self.notify_collections_staff(bill)
+#
+# def complete_collections(self, activation):
+# """Finalize the collections process"""
+# process = activation.process
+# bill = process.medical_bill
+#
+# # Mark process as completed
+# process.collections_resolved = True
+# process.save()
+#
+# # Send completion notifications
+# self.notify_collections_completion(bill)
+#
+# def end_collections(self, activation):
+# """End the collections workflow"""
+# process = activation.process
+#
+# # Generate collections summary
+# self.generate_collections_summary(process.medical_bill)
+#
+# # Helper methods
+# def notify_collections_staff(self, bill):
+# """Notify collections staff"""
+# collections_staff = User.objects.filter(
+# groups__name='Collections Staff'
+# )
+#
+# for staff in collections_staff:
+# send_mail(
+# subject=f'Collections Account: {bill.bill_number}',
+# message=f'Account for {bill.patient.get_full_name()} requires collections action.',
+# from_email='collections@hospital.com',
+# recipient_list=[staff.email],
+# fail_silently=True
+# )
+#
+# def notify_collections_completion(self, bill):
+# """Notify collections completion"""
+# # This would notify relevant parties
+# pass
+#
+# def generate_collections_summary(self, bill):
+# """Generate collections summary"""
+# # This would generate collections summary
+# pass
+#
+#
+# # Celery tasks for background processing
+# @celery.job
+# def auto_generate_bills():
+# """Background task to automatically generate bills"""
+# try:
+# # This would generate bills for completed services
+# return True
+# except Exception:
+# return False
+#
+#
+# @celery.job
+# def monitor_claim_status():
+# """Background task to monitor insurance claim status"""
+# try:
+# # This would check claim status with insurance companies
+# return True
+# except Exception:
+# return False
+#
+#
+# @celery.job
+# def generate_billing_reports():
+# """Background task to generate billing reports"""
+# try:
+# # This would generate daily billing reports
+# return True
+# except Exception:
+# return False
+#
+#
+# @celery.job
+# def auto_post_insurance_payments():
+# """Background task to automatically post insurance payments"""
+# try:
+# # This would post insurance payments from EDI files
+# return True
+# except Exception:
+# return False
+#
+#
+# @celery.job
+# def identify_collection_accounts():
+# """Background task to identify accounts for collections"""
+# try:
+# # This would identify overdue accounts
+# return True
+# except Exception:
+# return False
+#
diff --git a/billing/forms.py b/billing/forms.py
index 30aa60b9..44b2bd66 100644
--- a/billing/forms.py
+++ b/billing/forms.py
@@ -786,3 +786,790 @@ class PaymentSearchForm(forms.Form):
})
)
+
+# from django import forms
+# from django.core.exceptions import ValidationError
+# from django.utils import timezone
+# from django.contrib.auth.models import User
+# from crispy_forms.helper import FormHelper
+# from crispy_forms.layout import Layout, Fieldset, Submit, Row, Column, HTML, Div
+# from crispy_forms.bootstrap import FormActions
+# from decimal import Decimal
+# import json
+#
+# from .models import (
+# Bill, BillItem, InsuranceClaim, Payment, PaymentMethod,
+# InsuranceProvider, ClaimDenial, PaymentPlan
+# )
+# from patients.models import Patient
+#
+#
+# class MedicalBillingForm(forms.ModelForm):
+# """
+# Form for medical billing creation
+# """
+# patient_search = forms.CharField(
+# required=False,
+# widget=forms.TextInput(attrs={
+# 'class': 'form-control',
+# 'placeholder': 'Search patient by name, ID, or insurance...',
+# 'data-toggle': 'patient-search'
+# })
+# )
+# insurance_verification = forms.BooleanField(
+# required=False,
+# initial=True,
+# widget=forms.CheckboxInput(attrs={'class': 'form-check-input'})
+# )
+# auto_submit_primary = forms.BooleanField(
+# required=False,
+# initial=True,
+# widget=forms.CheckboxInput(attrs={'class': 'form-check-input'})
+# )
+# auto_submit_secondary = forms.BooleanField(
+# required=False,
+# widget=forms.CheckboxInput(attrs={'class': 'form-check-input'})
+# )
+# generate_patient_statement = forms.BooleanField(
+# required=False,
+# initial=True,
+# widget=forms.CheckboxInput(attrs={'class': 'form-check-input'})
+# )
+#
+# class Meta:
+# model = Bill
+# fields = [
+# 'patient', 'encounter', 'bill_type', 'service_date',
+# 'diagnosis_codes', 'procedure_codes', 'provider',
+# 'facility', 'insurance_verification', 'auto_submit_primary',
+# 'auto_submit_secondary', 'generate_patient_statement'
+# ]
+# widgets = {
+# 'patient': forms.Select(attrs={'class': 'form-control'}),
+# 'encounter': forms.Select(attrs={'class': 'form-control'}),
+# 'bill_type': forms.Select(attrs={'class': 'form-control'}),
+# 'service_date': forms.DateInput(attrs={'class': 'form-control', 'type': 'date'}),
+# 'diagnosis_codes': forms.Textarea(attrs={'class': 'form-control', 'rows': 3}),
+# 'procedure_codes': forms.Textarea(attrs={'class': 'form-control', 'rows': 3}),
+# 'provider': forms.Select(attrs={'class': 'form-control'}),
+# 'facility': forms.Select(attrs={'class': 'form-control'})
+# }
+#
+# def __init__(self, *args, **kwargs):
+# tenant = kwargs.pop('tenant', None)
+# super().__init__(*args, **kwargs)
+#
+# if tenant:
+# self.fields['patient'].queryset = Patient.objects.filter(tenant=tenant)
+# self.fields['provider'].queryset = User.objects.filter(
+# tenant=tenant,
+# groups__name__in=['Doctors', 'Nurses', 'Specialists']
+# )
+#
+# self.helper = FormHelper()
+# self.helper.layout = Layout(
+# Fieldset(
+# 'Patient Information',
+# 'patient_search',
+# 'patient',
+# 'encounter'
+# ),
+# Fieldset(
+# 'Service Details',
+# Row(
+# Column('bill_type', css_class='form-group col-md-6 mb-0'),
+# Column('service_date', css_class='form-group col-md-6 mb-0'),
+# css_class='form-row'
+# ),
+# Row(
+# Column('provider', css_class='form-group col-md-6 mb-0'),
+# Column('facility', css_class='form-group col-md-6 mb-0'),
+# css_class='form-row'
+# ),
+# 'diagnosis_codes',
+# 'procedure_codes'
+# ),
+# Fieldset(
+# 'Billing Options',
+# HTML(''),
+# 'insurance_verification',
+# HTML(
+# ''),
+# HTML('
'),
+# HTML(''),
+# 'auto_submit_primary',
+# HTML(
+# ''),
+# HTML('
'),
+# HTML(''),
+# 'auto_submit_secondary',
+# HTML(
+# ''),
+# HTML('
'),
+# HTML(''),
+# 'generate_patient_statement',
+# HTML(
+# ''),
+# HTML('
')
+# ),
+# FormActions(
+# Submit('submit', 'Create Bill', css_class='btn btn-primary'),
+# HTML('Cancel')
+# )
+# )
+#
+# def clean_diagnosis_codes(self):
+# codes = self.cleaned_data.get('diagnosis_codes')
+# if codes:
+# # Validate ICD-10 codes format
+# code_list = [code.strip() for code in codes.split(',')]
+# for code in code_list:
+# if not self.validate_icd10_code(code):
+# raise ValidationError(f'Invalid ICD-10 code format: {code}')
+# return codes
+#
+# def clean_procedure_codes(self):
+# codes = self.cleaned_data.get('procedure_codes')
+# if codes:
+# # Validate CPT codes format
+# code_list = [code.strip() for code in codes.split(',')]
+# for code in code_list:
+# if not self.validate_cpt_code(code):
+# raise ValidationError(f'Invalid CPT code format: {code}')
+# return codes
+#
+# def validate_icd10_code(self, code):
+# """Validate ICD-10 code format"""
+# # Basic ICD-10 validation (simplified)
+# return len(code) >= 3 and code[0].isalpha()
+#
+# def validate_cpt_code(self, code):
+# """Validate CPT code format"""
+# # Basic CPT validation (simplified)
+# return len(code) == 5 and code.isdigit()
+#
+#
+# class BillItemForm(forms.ModelForm):
+# """
+# Form for bill item creation/editing
+# """
+# quantity = forms.DecimalField(
+# max_digits=10,
+# decimal_places=2,
+# initial=1.00,
+# widget=forms.NumberInput(attrs={'class': 'form-control', 'step': '0.01'})
+# )
+# unit_price = forms.DecimalField(
+# max_digits=10,
+# decimal_places=2,
+# widget=forms.NumberInput(attrs={'class': 'form-control', 'step': '0.01'})
+# )
+# discount_amount = forms.DecimalField(
+# max_digits=10,
+# decimal_places=2,
+# initial=0.00,
+# required=False,
+# widget=forms.NumberInput(attrs={'class': 'form-control', 'step': '0.01'})
+# )
+#
+# class Meta:
+# model = BillItem
+# fields = [
+# 'service_code', 'description', 'quantity', 'unit_price',
+# 'discount_amount', 'modifier_codes', 'revenue_code'
+# ]
+# widgets = {
+# 'service_code': forms.TextInput(attrs={'class': 'form-control'}),
+# 'description': forms.Textarea(attrs={'class': 'form-control', 'rows': 2}),
+# 'modifier_codes': forms.TextInput(attrs={'class': 'form-control'}),
+# 'revenue_code': forms.TextInput(attrs={'class': 'form-control'})
+# }
+#
+# def __init__(self, *args, **kwargs):
+# super().__init__(*args, **kwargs)
+#
+# self.helper = FormHelper()
+# self.helper.layout = Layout(
+# Fieldset(
+# 'Service Information',
+# Row(
+# Column('service_code', css_class='form-group col-md-6 mb-0'),
+# Column('revenue_code', css_class='form-group col-md-6 mb-0'),
+# css_class='form-row'
+# ),
+# 'description',
+# 'modifier_codes'
+# ),
+# Fieldset(
+# 'Pricing',
+# Row(
+# Column('quantity', css_class='form-group col-md-4 mb-0'),
+# Column('unit_price', css_class='form-group col-md-4 mb-0'),
+# Column('discount_amount', css_class='form-group col-md-4 mb-0'),
+# css_class='form-row'
+# )
+# ),
+# FormActions(
+# Submit('submit', 'Save Item', css_class='btn btn-primary'),
+# HTML('')
+# )
+# )
+#
+# def clean(self):
+# cleaned_data = super().clean()
+# quantity = cleaned_data.get('quantity')
+# unit_price = cleaned_data.get('unit_price')
+# discount_amount = cleaned_data.get('discount_amount', Decimal('0.00'))
+#
+# if quantity and unit_price:
+# total_amount = quantity * unit_price
+# if discount_amount > total_amount:
+# raise ValidationError('Discount amount cannot exceed total amount.')
+#
+# return cleaned_data
+#
+#
+# class InsuranceClaimForm(forms.ModelForm):
+# """
+# Form for insurance claim submission
+# """
+# claim_type = forms.ChoiceField(
+# choices=[
+# ('primary', 'Primary Insurance'),
+# ('secondary', 'Secondary Insurance'),
+# ('tertiary', 'Tertiary Insurance')
+# ],
+# required=True,
+# widget=forms.Select(attrs={'class': 'form-control'})
+# )
+# submit_electronically = forms.BooleanField(
+# required=False,
+# initial=True,
+# widget=forms.CheckboxInput(attrs={'class': 'form-check-input'})
+# )
+# prior_authorization = forms.CharField(
+# required=False,
+# widget=forms.TextInput(attrs={'class': 'form-control'})
+# )
+# referral_number = forms.CharField(
+# required=False,
+# widget=forms.TextInput(attrs={'class': 'form-control'})
+# )
+#
+# class Meta:
+# model = InsuranceClaim
+# fields = [
+# 'bill', 'insurance_provider', 'claim_type', 'policy_number',
+# 'group_number', 'subscriber_id', 'prior_authorization',
+# 'referral_number', 'submit_electronically'
+# ]
+# widgets = {
+# 'bill': forms.Select(attrs={'class': 'form-control'}),
+# 'insurance_provider': forms.Select(attrs={'class': 'form-control'}),
+# 'policy_number': forms.TextInput(attrs={'class': 'form-control'}),
+# 'group_number': forms.TextInput(attrs={'class': 'form-control'}),
+# 'subscriber_id': forms.TextInput(attrs={'class': 'form-control'})
+# }
+#
+# def __init__(self, *args, **kwargs):
+# tenant = kwargs.pop('tenant', None)
+# super().__init__(*args, **kwargs)
+#
+# if tenant:
+# self.fields['bill'].queryset = Bill.objects.filter(tenant=tenant)
+# self.fields['insurance_provider'].queryset = InsuranceProvider.objects.filter(tenant=tenant)
+#
+# self.helper = FormHelper()
+# self.helper.layout = Layout(
+# Fieldset(
+# 'Claim Information',
+# Row(
+# Column('bill', css_class='form-group col-md-6 mb-0'),
+# Column('claim_type', css_class='form-group col-md-6 mb-0'),
+# css_class='form-row'
+# ),
+# 'insurance_provider'
+# ),
+# Fieldset(
+# 'Insurance Details',
+# Row(
+# Column('policy_number', css_class='form-group col-md-6 mb-0'),
+# Column('group_number', css_class='form-group col-md-6 mb-0'),
+# css_class='form-row'
+# ),
+# 'subscriber_id'
+# ),
+# Fieldset(
+# 'Authorization',
+# Row(
+# Column('prior_authorization', css_class='form-group col-md-6 mb-0'),
+# Column('referral_number', css_class='form-group col-md-6 mb-0'),
+# css_class='form-row'
+# )
+# ),
+# Fieldset(
+# 'Submission Options',
+# HTML(''),
+# 'submit_electronically',
+# HTML(''),
+# HTML('
')
+# ),
+# FormActions(
+# Submit('submit', 'Submit Claim', css_class='btn btn-primary'),
+# HTML('Cancel')
+# )
+# )
+#
+#
+# class PaymentProcessingForm(forms.ModelForm):
+# """
+# Form for payment processing
+# """
+# payment_amount = forms.DecimalField(
+# max_digits=10,
+# decimal_places=2,
+# widget=forms.NumberInput(attrs={'class': 'form-control', 'step': '0.01'})
+# )
+# payment_date = forms.DateField(
+# initial=timezone.now().date(),
+# widget=forms.DateInput(attrs={'class': 'form-control', 'type': 'date'})
+# )
+# reference_number = forms.CharField(
+# required=False,
+# widget=forms.TextInput(attrs={'class': 'form-control'})
+# )
+# notes = forms.CharField(
+# required=False,
+# widget=forms.Textarea(attrs={'class': 'form-control', 'rows': 3})
+# )
+# send_receipt = forms.BooleanField(
+# required=False,
+# initial=True,
+# widget=forms.CheckboxInput(attrs={'class': 'form-check-input'})
+# )
+#
+# class Meta:
+# model = Payment
+# fields = [
+# 'bill', 'payment_method', 'payment_source', 'payment_amount',
+# 'payment_date', 'reference_number', 'notes', 'send_receipt'
+# ]
+# widgets = {
+# 'bill': forms.Select(attrs={'class': 'form-control'}),
+# 'payment_method': forms.Select(attrs={'class': 'form-control'}),
+# 'payment_source': forms.Select(attrs={'class': 'form-control'})
+# }
+#
+# def __init__(self, *args, **kwargs):
+# tenant = kwargs.pop('tenant', None)
+# bill = kwargs.pop('bill', None)
+# super().__init__(*args, **kwargs)
+#
+# if tenant:
+# self.fields['bill'].queryset = Bill.objects.filter(tenant=tenant)
+# self.fields['payment_method'].queryset = PaymentMethod.objects.filter(tenant=tenant)
+#
+# if bill:
+# self.fields['bill'].initial = bill
+# self.fields['payment_amount'].initial = bill.balance_due
+#
+# self.helper = FormHelper()
+# self.helper.layout = Layout(
+# Fieldset(
+# 'Payment Information',
+# Row(
+# Column('bill', css_class='form-group col-md-6 mb-0'),
+# Column('payment_source', css_class='form-group col-md-6 mb-0'),
+# css_class='form-row'
+# ),
+# Row(
+# Column('payment_method', css_class='form-group col-md-6 mb-0'),
+# Column('payment_amount', css_class='form-group col-md-6 mb-0'),
+# css_class='form-row'
+# ),
+# Row(
+# Column('payment_date', css_class='form-group col-md-6 mb-0'),
+# Column('reference_number', css_class='form-group col-md-6 mb-0'),
+# css_class='form-row'
+# ),
+# 'notes'
+# ),
+# Fieldset(
+# 'Options',
+# HTML(''),
+# 'send_receipt',
+# HTML(''),
+# HTML('
')
+# ),
+# FormActions(
+# Submit('submit', 'Process Payment', css_class='btn btn-primary'),
+# HTML('Cancel')
+# )
+# )
+#
+# def clean_payment_amount(self):
+# payment_amount = self.cleaned_data.get('payment_amount')
+# bill = self.cleaned_data.get('bill')
+#
+# if payment_amount and bill:
+# if payment_amount > bill.balance_due:
+# raise ValidationError('Payment amount cannot exceed balance due.')
+# if payment_amount <= 0:
+# raise ValidationError('Payment amount must be greater than zero.')
+#
+# return payment_amount
+#
+#
+# class DenialManagementForm(forms.ModelForm):
+# """
+# Form for denial management
+# """
+# denial_reason = forms.ChoiceField(
+# choices=[
+# ('invalid_code', 'Invalid Procedure/Diagnosis Code'),
+# ('not_covered', 'Service Not Covered'),
+# ('prior_auth', 'Prior Authorization Required'),
+# ('duplicate', 'Duplicate Claim'),
+# ('incomplete', 'Incomplete Information'),
+# ('timely_filing', 'Timely Filing Limit Exceeded'),
+# ('other', 'Other')
+# ],
+# required=True,
+# widget=forms.Select(attrs={'class': 'form-control'})
+# )
+# appeal_deadline = forms.DateField(
+# required=False,
+# widget=forms.DateInput(attrs={'class': 'form-control', 'type': 'date'})
+# )
+# corrective_action = forms.CharField(
+# required=False,
+# widget=forms.Textarea(attrs={'class': 'form-control', 'rows': 4})
+# )
+# resubmit_claim = forms.BooleanField(
+# required=False,
+# widget=forms.CheckboxInput(attrs={'class': 'form-check-input'})
+# )
+# file_appeal = forms.BooleanField(
+# required=False,
+# widget=forms.CheckboxInput(attrs={'class': 'form-check-input'})
+# )
+#
+# class Meta:
+# model = ClaimDenial
+# fields = [
+# 'claim', 'denial_reason', 'denial_description', 'denied_amount',
+# 'appeal_deadline', 'corrective_action', 'resubmit_claim', 'file_appeal'
+# ]
+# widgets = {
+# 'claim': forms.Select(attrs={'class': 'form-control'}),
+# 'denial_description': forms.Textarea(attrs={'class': 'form-control', 'rows': 3}),
+# 'denied_amount': forms.NumberInput(attrs={'class': 'form-control', 'step': '0.01'})
+# }
+#
+# def __init__(self, *args, **kwargs):
+# tenant = kwargs.pop('tenant', None)
+# super().__init__(*args, **kwargs)
+#
+# if tenant:
+# self.fields['claim'].queryset = InsuranceClaim.objects.filter(tenant=tenant)
+#
+# self.helper = FormHelper()
+# self.helper.layout = Layout(
+# Fieldset(
+# 'Denial Information',
+# 'claim',
+# Row(
+# Column('denial_reason', css_class='form-group col-md-6 mb-0'),
+# Column('denied_amount', css_class='form-group col-md-6 mb-0'),
+# css_class='form-row'
+# ),
+# 'denial_description',
+# 'appeal_deadline'
+# ),
+# Fieldset(
+# 'Corrective Actions',
+# 'corrective_action',
+# HTML(''),
+# 'resubmit_claim',
+# HTML(''),
+# HTML('
'),
+# HTML(''),
+# 'file_appeal',
+# HTML(''),
+# HTML('
')
+# ),
+# FormActions(
+# Submit('submit', 'Process Denial', css_class='btn btn-primary'),
+# HTML('Cancel')
+# )
+# )
+#
+#
+# class PaymentPlanForm(forms.ModelForm):
+# """
+# Form for payment plan setup
+# """
+# plan_type = forms.ChoiceField(
+# choices=[
+# ('monthly', 'Monthly Payments'),
+# ('weekly', 'Weekly Payments'),
+# ('biweekly', 'Bi-weekly Payments'),
+# ('custom', 'Custom Schedule')
+# ],
+# required=True,
+# widget=forms.Select(attrs={'class': 'form-control'})
+# )
+# number_of_payments = forms.IntegerField(
+# min_value=2,
+# max_value=60,
+# widget=forms.NumberInput(attrs={'class': 'form-control'})
+# )
+# payment_amount = forms.DecimalField(
+# max_digits=10,
+# decimal_places=2,
+# widget=forms.NumberInput(attrs={'class': 'form-control', 'step': '0.01'})
+# )
+# first_payment_date = forms.DateField(
+# widget=forms.DateInput(attrs={'class': 'form-control', 'type': 'date'})
+# )
+# auto_payment = forms.BooleanField(
+# required=False,
+# widget=forms.CheckboxInput(attrs={'class': 'form-check-input'})
+# )
+#
+# class Meta:
+# model = PaymentPlan
+# fields = [
+# 'bill', 'plan_type', 'total_amount', 'number_of_payments',
+# 'payment_amount', 'first_payment_date', 'auto_payment'
+# ]
+# widgets = {
+# 'bill': forms.Select(attrs={'class': 'form-control'}),
+# 'total_amount': forms.NumberInput(attrs={'class': 'form-control', 'step': '0.01'})
+# }
+#
+# def __init__(self, *args, **kwargs):
+# tenant = kwargs.pop('tenant', None)
+# super().__init__(*args, **kwargs)
+#
+# if tenant:
+# self.fields['bill'].queryset = Bill.objects.filter(tenant=tenant, balance_due__gt=0)
+#
+# # Set minimum date to tomorrow
+# tomorrow = timezone.now().date() + timezone.timedelta(days=1)
+# self.fields['first_payment_date'].widget.attrs['min'] = tomorrow.isoformat()
+#
+# self.helper = FormHelper()
+# self.helper.layout = Layout(
+# Fieldset(
+# 'Payment Plan Details',
+# 'bill',
+# Row(
+# Column('plan_type', css_class='form-group col-md-6 mb-0'),
+# Column('total_amount', css_class='form-group col-md-6 mb-0'),
+# css_class='form-row'
+# ),
+# Row(
+# Column('number_of_payments', css_class='form-group col-md-6 mb-0'),
+# Column('payment_amount', css_class='form-group col-md-6 mb-0'),
+# css_class='form-row'
+# ),
+# 'first_payment_date'
+# ),
+# Fieldset(
+# 'Options',
+# HTML(''),
+# 'auto_payment',
+# HTML(''),
+# HTML('
')
+# ),
+# FormActions(
+# Submit('submit', 'Create Payment Plan', css_class='btn btn-primary'),
+# HTML('Cancel')
+# )
+# )
+#
+# def clean(self):
+# cleaned_data = super().clean()
+# total_amount = cleaned_data.get('total_amount')
+# number_of_payments = cleaned_data.get('number_of_payments')
+# payment_amount = cleaned_data.get('payment_amount')
+#
+# if total_amount and number_of_payments and payment_amount:
+# calculated_total = payment_amount * number_of_payments
+# if abs(calculated_total - total_amount) > Decimal('0.01'):
+# raise ValidationError('Payment amount × number of payments must equal total amount.')
+#
+# return cleaned_data
+#
+#
+# class CollectionsForm(forms.Form):
+# """
+# Form for collections management
+# """
+# collection_action = forms.ChoiceField(
+# choices=[
+# ('letter_1', 'Send First Collection Letter'),
+# ('letter_2', 'Send Second Collection Letter'),
+# ('letter_3', 'Send Final Collection Letter'),
+# ('phone_call', 'Schedule Phone Call'),
+# ('external_agency', 'Send to External Agency'),
+# ('write_off', 'Write Off Balance')
+# ],
+# required=True,
+# widget=forms.Select(attrs={'class': 'form-control'})
+# )
+# collection_notes = forms.CharField(
+# required=False,
+# widget=forms.Textarea(attrs={'class': 'form-control', 'rows': 4})
+# )
+# follow_up_date = forms.DateField(
+# required=False,
+# widget=forms.DateInput(attrs={'class': 'form-control', 'type': 'date'})
+# )
+# write_off_reason = forms.ChoiceField(
+# choices=[
+# ('uncollectible', 'Uncollectible'),
+# ('patient_deceased', 'Patient Deceased'),
+# ('bankruptcy', 'Bankruptcy'),
+# ('small_balance', 'Small Balance'),
+# ('other', 'Other')
+# ],
+# required=False,
+# widget=forms.Select(attrs={'class': 'form-control'})
+# )
+#
+# def __init__(self, *args, **kwargs):
+# super().__init__(*args, **kwargs)
+#
+# self.helper = FormHelper()
+# self.helper.layout = Layout(
+# Fieldset(
+# 'Collection Action',
+# 'collection_action',
+# 'collection_notes',
+# 'follow_up_date'
+# ),
+# Fieldset(
+# 'Write-off Details',
+# 'write_off_reason',
+# HTML('Required only for write-off actions')
+# ),
+# FormActions(
+# Submit('submit', 'Execute Collection Action', css_class='btn btn-primary'),
+# HTML('Cancel')
+# )
+# )
+#
+#
+# class InsuranceVerificationForm(forms.Form):
+# """
+# Form for insurance verification
+# """
+# verification_type = forms.ChoiceField(
+# choices=[
+# ('eligibility', 'Eligibility Verification'),
+# ('benefits', 'Benefits Verification'),
+# ('authorization', 'Prior Authorization'),
+# ('referral', 'Referral Verification')
+# ],
+# required=True,
+# widget=forms.Select(attrs={'class': 'form-control'})
+# )
+# service_date = forms.DateField(
+# widget=forms.DateInput(attrs={'class': 'form-control', 'type': 'date'})
+# )
+# procedure_codes = forms.CharField(
+# widget=forms.Textarea(attrs={'class': 'form-control', 'rows': 3})
+# )
+# verification_notes = forms.CharField(
+# required=False,
+# widget=forms.Textarea(attrs={'class': 'form-control', 'rows': 4})
+# )
+#
+# def __init__(self, *args, **kwargs):
+# super().__init__(*args, **kwargs)
+#
+# self.helper = FormHelper()
+# self.helper.layout = Layout(
+# Fieldset(
+# 'Verification Details',
+# Row(
+# Column('verification_type', css_class='form-group col-md-6 mb-0'),
+# Column('service_date', css_class='form-group col-md-6 mb-0'),
+# css_class='form-row'
+# ),
+# 'procedure_codes',
+# 'verification_notes'
+# ),
+# FormActions(
+# Submit('submit', 'Verify Insurance', css_class='btn btn-primary'),
+# HTML('Cancel')
+# )
+# )
+#
+#
+# class BulkBillingForm(forms.Form):
+# """
+# Form for bulk billing operations
+# """
+# action = forms.ChoiceField(
+# choices=[
+# ('submit_claims', 'Submit Claims'),
+# ('generate_statements', 'Generate Patient Statements'),
+# ('send_reminders', 'Send Payment Reminders'),
+# ('update_status', 'Update Status'),
+# ('apply_adjustments', 'Apply Adjustments')
+# ],
+# required=True,
+# widget=forms.Select(attrs={'class': 'form-control'})
+# )
+# bill_ids = forms.CharField(
+# widget=forms.HiddenInput()
+# )
+# new_status = forms.ChoiceField(
+# choices=[
+# ('pending', 'Pending'),
+# ('submitted', 'Submitted'),
+# ('paid', 'Paid'),
+# ('denied', 'Denied'),
+# ('cancelled', 'Cancelled')
+# ],
+# required=False,
+# widget=forms.Select(attrs={'class': 'form-control'})
+# )
+# adjustment_amount = forms.DecimalField(
+# max_digits=10,
+# decimal_places=2,
+# required=False,
+# widget=forms.NumberInput(attrs={'class': 'form-control', 'step': '0.01'})
+# )
+# adjustment_reason = forms.CharField(
+# required=False,
+# widget=forms.Textarea(attrs={'class': 'form-control', 'rows': 3})
+# )
+#
+# def __init__(self, *args, **kwargs):
+# super().__init__(*args, **kwargs)
+#
+# self.helper = FormHelper()
+# self.helper.layout = Layout(
+# 'bill_ids',
+# Fieldset(
+# 'Bulk Operation',
+# 'action',
+# 'new_status',
+# Row(
+# Column('adjustment_amount', css_class='form-group col-md-6 mb-0'),
+# css_class='form-row'
+# ),
+# 'adjustment_reason'
+# ),
+# FormActions(
+# Submit('submit', 'Execute Bulk Operation', css_class='btn btn-primary'),
+# HTML('Cancel')
+# )
+# )
+#
+#
+#
diff --git a/billing/urls.py b/billing/urls.py
index a60e0c98..1e5d7bd9 100644
--- a/billing/urls.py
+++ b/billing/urls.py
@@ -14,6 +14,8 @@ urlpatterns = [
# Medical Bills
path('bills/', views.MedicalBillListView.as_view(), name='bill_list'),
path('bills//', views.MedicalBillDetailView.as_view(), name='bill_detail'),
+ path('bills//', views.bill_details_api, name='bill_details_api'),
+ path('bills//line-items', views.bill_line_items_api, name='bill_line_items_api'),
path('bills/create/', views.MedicalBillCreateView.as_view(), name='bill_create'),
path('bills//edit/', views.MedicalBillUpdateView.as_view(), name='bill_update'),
path('bills//delete/', views.MedicalBillDeleteView.as_view(), name='bill_delete'),
@@ -40,14 +42,15 @@ urlpatterns = [
path('bills//payments/create/', views.PaymentCreateView.as_view(), name='bill_payment_create'),
# HTMX endpoints
- path('htmx/stats/', views.htmx_billing_stats, name='billing_stats'),
- path('htmx/bill-search/', views.htmx_bill_search, name='bill_search'),
+ path('stats/bills/', views.billing_stats, name='billing_stats'),
+ path('bill-search/', views.bill_search, name='bill_search'),
# Action endpoints
path('bills//submit/', views.submit_bill, name='submit_bill'),
# Export endpoints
path('export/bills/', views.export_bills, name='export_bills'),
+ path('export/claims/', views.export_claims, name='export_claims'),
# API endpoints
# path('api/', include('billing.api.urls')),
diff --git a/billing/views.py b/billing/views.py
index 59282afe..f8edfbb2 100644
--- a/billing/views.py
+++ b/billing/views.py
@@ -393,7 +393,7 @@ class InsuranceClaimDetailView(LoginRequiredMixin, DetailView):
claim = self.get_object()
# Get related data
- context['status_updates'] = claim.claimstatusupdate_set.all().order_by('-update_date')
+ # context['status_updates'] = claim.claimstatusupdate_set.all().order_by('-update_date')
return context
@@ -426,8 +426,8 @@ class InsuranceClaimCreateView(LoginRequiredMixin, PermissionRequiredMixin, Crea
return kwargs
def form_valid(self, form):
- # Set medical bill and created_by
- bill_id = self.kwargs.get('bill_id')
+ # Prefer URL bill_id; otherwise read from POST("medical_bill")
+ bill_id = self.kwargs.get('bill_id') or self.request.POST.get('medical_bill')
if bill_id:
try:
medical_bill = MedicalBill.objects.get(
@@ -438,22 +438,25 @@ class InsuranceClaimCreateView(LoginRequiredMixin, PermissionRequiredMixin, Crea
except MedicalBill.DoesNotExist:
messages.error(self.request, 'Medical bill not found.')
return redirect('billing:bill_list')
-
+ else:
+ messages.error(self.request, 'Please select a medical bill.')
+ return redirect('billing:claim_create')
+
form.instance.created_by = self.request.user
-
- # Generate claim number
+
if not form.instance.claim_number:
form.instance.claim_number = form.instance.generate_claim_number()
-
+
response = super().form_valid(form)
-
- messages.success(
- self.request,
- f'Insurance claim {self.object.claim_number} created successfully.'
- )
-
+ messages.success(self.request, f'Insurance claim {self.object.claim_number} created successfully.')
return response
-
+
+ def get_context_data(self, **kwargs):
+ ctx = super().get_context_data(**kwargs)
+ tenant = getattr(self.request, 'tenant', None)
+ ctx['available_bills'] = MedicalBill.objects.filter(tenant=tenant).select_related('patient')
+ return ctx
+
def get_success_url(self):
return reverse('billing:claim_detail', kwargs={'claim_id': self.object.claim_id})
@@ -631,7 +634,7 @@ class PaymentCreateView(LoginRequiredMixin, PermissionRequiredMixin, CreateView)
# return JsonResponse(stats)
@login_required
-def htmx_billing_stats(request):
+def billing_stats(request):
"""
HTMX view for billing statistics.
"""
@@ -690,7 +693,30 @@ def htmx_billing_stats(request):
@login_required
-def htmx_bill_search(request):
+def bill_details_api(request, bill_id):
+ tenant = getattr(request, 'tenant', None)
+ if not tenant:
+ return JsonResponse({'error': 'No tenant found'}, status=400)
+
+ bill = get_object_or_404(
+ MedicalBill.objects.select_related('patient', 'billing_provider'),
+ bill_id=bill_id,
+ tenant=tenant,
+ )
+
+ data = {
+ 'patient_name': bill.patient.get_full_name() if bill.patient else '',
+ 'bill_number': bill.bill_number or '',
+ 'bill_date': bill.bill_date.isoformat() if bill.bill_date else '',
+ 'total_amount': str(bill.total_amount or 0),
+ 'service_date_from': bill.service_date_from.isoformat() if bill.service_date_from else '',
+ 'service_date_to': bill.service_date_to.isoformat() if bill.service_date_to else '',
+ 'billing_provider': bill.billing_provider.get_full_name() if bill.billing_provider else '',
+ }
+ return JsonResponse(data)
+
+@login_required
+def bill_search(request):
"""
HTMX endpoint for bill search.
"""
@@ -1391,6 +1417,145 @@ def payment_download(request, payment_id):
messages.error(request, f'Error generating PDF: {str(e)}')
return redirect('billing:payment_receipt', payment_id=payment_id)
+
+@login_required
+def export_claims(request):
+ """
+ Export insurance claims to CSV.
+ Supports optional filtering by 'claims' GET param: ?claims=ID1,ID2,ID3
+ """
+ tenant = getattr(request, 'tenant', None)
+ if not tenant:
+ return HttpResponse('No tenant found', status=400)
+
+ # Base queryset
+ qs = InsuranceClaim.objects.filter(tenant=tenant).select_related(
+ 'medical_bill__patient',
+ 'insurance_info',
+ )
+
+ # Optional selection filter (comma-separated claim_ids)
+ selected = request.GET.get('claims')
+ if selected:
+ claim_ids = [c.strip() for c in selected.split(',') if c.strip()]
+ if claim_ids:
+ qs = qs.filter(claim_id__in=claim_ids)
+
+ # Prepare CSV response
+ response = HttpResponse(content_type='text/csv')
+ response['Content-Disposition'] = 'attachment; filename="insurance_claims.csv"'
+
+ writer = csv.writer(response)
+ writer.writerow([
+ 'Claim Number',
+ 'Bill Number',
+ 'Patient Name',
+ 'Insurance Company',
+ 'Claim Type',
+ 'Service From',
+ 'Service To',
+ 'Billed Amount',
+ 'Status',
+ ])
+
+ for claim in qs:
+ bill = getattr(claim, 'medical_bill', None)
+ patient = getattr(bill, 'patient', None)
+
+ # Safely get nice display values
+ insurance_company = getattr(getattr(claim, 'insurance_info', None), 'company', None)
+ if not insurance_company:
+ # Fallback to __str__ of insurance_info or empty
+ insurance_company = str(getattr(claim, 'insurance_info', '')) or ''
+
+ claim_type = getattr(claim, 'get_claim_type_display', None)
+ if callable(claim_type):
+ claim_type = claim.get_claim_type_display()
+ else:
+ claim_type = getattr(claim, 'claim_type', '') or ''
+
+ status_val = ''
+ get_status_display = getattr(claim, 'get_status_display', None)
+ if callable(get_status_display):
+ status_val = claim.get_status_display()
+ else:
+ # Fallback if no choices helper exists
+ status_val = getattr(claim, 'status', '') or ''
+
+ writer.writerow([
+ getattr(claim, 'claim_number', '') or '',
+ getattr(bill, 'bill_number', '') if bill else '',
+ patient.get_full_name() if patient else '',
+ insurance_company,
+ claim_type,
+ claim.service_date_from.strftime('%Y-%m-%d') if getattr(claim, 'service_date_from', None) else '',
+ claim.service_date_to.strftime('%Y-%m-%d') if getattr(claim, 'service_date_to', None) else '',
+ str(getattr(claim, 'billed_amount', '')) or '0',
+ status_val,
+ ])
+
+ return response
+
+
+@login_required
+def bill_line_items_api(request, bill_id=None):
+ """
+ Return line items for a medical bill as JSON.
+ Supports:
+ - /api/bills//line-items/
+ - /api/bills/line-items/?bill_id=
+ """
+ tenant = getattr(request, 'tenant', None)
+ if not tenant:
+ return JsonResponse({'success': False, 'error': 'No tenant found'}, status=400)
+
+ bill_id = bill_id or request.GET.get('bill_id')
+ if not bill_id:
+ return JsonResponse({'success': False, 'error': 'bill_id is required'}, status=400)
+
+ bill = get_object_or_404(
+ MedicalBill.objects.select_related('patient').prefetch_related('billlineitem_set'),
+ bill_id=bill_id,
+ tenant=tenant,
+ )
+
+ # Prefer per-item service date if your model has it; otherwise fall back
+ bill_service_date = (
+ bill.service_date_from.isoformat() if getattr(bill, 'service_date_from', None)
+ else bill.bill_date.isoformat() if getattr(bill, 'bill_date', None)
+ else ''
+ )
+
+ items = []
+ for li in bill.billlineitem_set.all():
+ qty = getattr(li, 'quantity', 0) or 0
+ price = getattr(li, 'unit_price', Decimal('0')) or Decimal('0')
+ # If your BillLineItem has service_date, use it; otherwise default
+ li_service_date = getattr(li, 'service_date', None)
+ if li_service_date:
+ li_service_date = li_service_date.isoformat()
+ else:
+ li_service_date = bill_service_date
+
+ items.append({
+ 'id': getattr(li, 'id', None),
+ 'service_code': getattr(li, 'service_code', '') or '',
+ 'description': getattr(li, 'description', '') or '',
+ 'quantity': qty,
+ 'unit_price': str(price),
+ 'service_date': li_service_date,
+ 'total': str(price * Decimal(qty)),
+ })
+
+ return JsonResponse({
+ 'success': True,
+ 'bill_id': str(bill.bill_id),
+ 'patient_name': bill.patient.get_full_name() if bill.patient else '',
+ 'line_items': items,
+ })
+
+
+
#
#
# """
@@ -2159,3 +2324,503 @@ payment_list = PaymentListView.as_view()
#
#
#
+# from django.shortcuts import render, redirect, get_object_or_404
+# from django.contrib.auth.decorators import login_required, permission_required
+# from django.contrib.auth.mixins import LoginRequiredMixin, PermissionRequiredMixin
+# from django.contrib import messages
+# from django.views.generic import (
+# CreateView, UpdateView, DeleteView, DetailView, ListView, FormView
+# )
+# from django.urls import reverse_lazy, reverse
+# from django.http import JsonResponse, HttpResponse
+# from django.utils import timezone
+# from django.db import transaction
+# from django.core.mail import send_mail
+# from django.conf import settings
+# from django.db.models import Q, Sum, Count
+# from viewflow.views import CreateProcessView, UpdateProcessView
+# from decimal import Decimal
+# import json
+#
+# from .models import (
+# Bill, BillItem, InsuranceClaim, Payment, PaymentMethod,
+# InsuranceProvider, ClaimDenial, PaymentPlan
+# )
+# from .forms import (
+# MedicalBillingForm, BillItemForm, InsuranceClaimForm, PaymentProcessingForm,
+# DenialManagementForm, PaymentPlanForm, CollectionsForm,
+# InsuranceVerificationForm, BulkBillingForm
+# )
+# from .flows import MedicalBillingFlow, InsuranceClaimFlow, PaymentProcessingFlow, DenialManagementFlow, CollectionsFlow
+# from patients.models import Patient
+#
+#
+# class MedicalBillingView(LoginRequiredMixin, PermissionRequiredMixin, CreateProcessView):
+# """
+# View for medical billing workflow
+# """
+# model = Bill
+# form_class = MedicalBillingForm
+# template_name = 'billing/medical_billing.html'
+# permission_required = 'billing.can_create_bills'
+# flow_class = MedicalBillingFlow
+#
+# def get_form_kwargs(self):
+# kwargs = super().get_form_kwargs()
+# kwargs['tenant'] = self.request.user.tenant
+# return kwargs
+#
+# def form_valid(self, form):
+# with transaction.atomic():
+# # Create bill
+# bill = form.save(commit=False)
+# bill.tenant = self.request.user.tenant
+# bill.created_by = self.request.user
+# bill.status = 'draft'
+# bill.save()
+#
+# # Start medical billing workflow
+# process = self.flow_class.start.run(
+# bill=bill,
+# insurance_verification=form.cleaned_data.get('insurance_verification', True),
+# auto_submit_primary=form.cleaned_data.get('auto_submit_primary', True),
+# auto_submit_secondary=form.cleaned_data.get('auto_submit_secondary', False),
+# generate_patient_statement=form.cleaned_data.get('generate_patient_statement', True),
+# created_by=self.request.user
+# )
+#
+# messages.success(
+# self.request,
+# f'Medical bill created successfully for {bill.patient.get_full_name()}. '
+# f'Billing workflow initiated.'
+# )
+#
+# return redirect('billing:bill_detail', pk=bill.pk)
+#
+# def get_context_data(self, **kwargs):
+# context = super().get_context_data(**kwargs)
+# context['title'] = 'Create Medical Bill'
+# context['breadcrumbs'] = [
+# {'name': 'Home', 'url': reverse('core:dashboard')},
+# {'name': 'Billing', 'url': reverse('billing:dashboard')},
+# {'name': 'Bills', 'url': reverse('billing:bill_list')},
+# {'name': 'Create Bill', 'url': ''}
+# ]
+# return context
+#
+#
+# class BillItemView(LoginRequiredMixin, PermissionRequiredMixin, CreateView):
+# """
+# View for bill item creation/editing
+# """
+# model = BillItem
+# form_class = BillItemForm
+# template_name = 'billing/bill_item_form.html'
+# permission_required = 'billing.can_edit_bill_items'
+#
+# def get_success_url(self):
+# return reverse('billing:bill_detail', kwargs={'pk': self.kwargs['bill_id']})
+#
+# def form_valid(self, form):
+# bill = get_object_or_404(Bill, pk=self.kwargs['bill_id'])
+#
+# with transaction.atomic():
+# # Create bill item
+# item = form.save(commit=False)
+# item.bill = bill
+# item.tenant = bill.tenant
+# item.save()
+#
+# # Recalculate bill totals
+# self.recalculate_bill_totals(bill)
+#
+# messages.success(
+# self.request,
+# f'Bill item "{item.description}" added successfully.'
+# )
+#
+# return super().form_valid(form)
+#
+# def recalculate_bill_totals(self, bill):
+# """Recalculate bill totals"""
+# items = bill.items.all()
+# subtotal = sum(item.total_amount for item in items)
+#
+# bill.subtotal = subtotal
+# bill.total_amount = subtotal + bill.tax_amount
+# bill.balance_due = bill.total_amount - bill.paid_amount
+# bill.save()
+#
+# def get_context_data(self, **kwargs):
+# context = super().get_context_data(**kwargs)
+# context['bill'] = get_object_or_404(Bill, pk=self.kwargs['bill_id'])
+# context['title'] = 'Add Bill Item'
+# return context
+#
+#
+# class InsuranceClaimView(LoginRequiredMixin, PermissionRequiredMixin, CreateProcessView):
+# """
+# View for insurance claim submission workflow
+# """
+# model = InsuranceClaim
+# form_class = InsuranceClaimForm
+# template_name = 'billing/insurance_claim.html'
+# permission_required = 'billing.can_submit_claims'
+# flow_class = InsuranceClaimFlow
+#
+# def get_form_kwargs(self):
+# kwargs = super().get_form_kwargs()
+# kwargs['tenant'] = self.request.user.tenant
+# return kwargs
+#
+# def form_valid(self, form):
+# with transaction.atomic():
+# # Create insurance claim
+# claim = form.save(commit=False)
+# claim.tenant = self.request.user.tenant
+# claim.submitted_by = self.request.user
+# claim.status = 'pending'
+# claim.save()
+#
+# # Start insurance claim workflow
+# process = self.flow_class.start.run(
+# claim=claim,
+# submit_electronically=form.cleaned_data.get('submit_electronically', True),
+# created_by=self.request.user
+# )
+#
+# messages.success(
+# self.request,
+# f'Insurance claim submitted successfully. Claim ID: {claim.claim_number}'
+# )
+#
+# return redirect('billing:claim_detail', pk=claim.pk)
+#
+# def get_context_data(self, **kwargs):
+# context = super().get_context_data(**kwargs)
+# context['title'] = 'Submit Insurance Claim'
+# context['breadcrumbs'] = [
+# {'name': 'Home', 'url': reverse('core:dashboard')},
+# {'name': 'Billing', 'url': reverse('billing:dashboard')},
+# {'name': 'Claims', 'url': reverse('billing:claim_list')},
+# {'name': 'Submit Claim', 'url': ''}
+# ]
+# return context
+#
+#
+# class PaymentProcessingView(LoginRequiredMixin, PermissionRequiredMixin, CreateProcessView):
+# """
+# View for payment processing workflow
+# """
+# model = Payment
+# form_class = PaymentProcessingForm
+# template_name = 'billing/payment_processing.html'
+# permission_required = 'billing.can_process_payments'
+# flow_class = PaymentProcessingFlow
+#
+# def get_form_kwargs(self):
+# kwargs = super().get_form_kwargs()
+# kwargs['tenant'] = self.request.user.tenant
+#
+# # Pre-populate bill if provided
+# bill_id = self.kwargs.get('bill_id')
+# if bill_id:
+# kwargs['bill'] = get_object_or_404(Bill, pk=bill_id)
+#
+# return kwargs
+#
+# def form_valid(self, form):
+# with transaction.atomic():
+# # Create payment
+# payment = form.save(commit=False)
+# payment.tenant = self.request.user.tenant
+# payment.processed_by = self.request.user
+# payment.status = 'pending'
+# payment.save()
+#
+# # Update bill balance
+# bill = payment.bill
+# bill.paid_amount += payment.payment_amount
+# bill.balance_due = bill.total_amount - bill.paid_amount
+#
+# if bill.balance_due <= 0:
+# bill.status = 'paid'
+# else:
+# bill.status = 'partial_payment'
+#
+# bill.save()
+#
+# # Start payment processing workflow
+# process = self.flow_class.start.run(
+# payment=payment,
+# send_receipt=form.cleaned_data.get('send_receipt', True),
+# created_by=self.request.user
+# )
+#
+# messages.success(
+# self.request,
+# f'Payment of ${payment.payment_amount} processed successfully. '
+# f'Remaining balance: ${bill.balance_due}'
+# )
+#
+# return redirect('billing:payment_detail', pk=payment.pk)
+#
+# def get_context_data(self, **kwargs):
+# context = super().get_context_data(**kwargs)
+# context['title'] = 'Process Payment'
+#
+# bill_id = self.kwargs.get('bill_id')
+# if bill_id:
+# context['bill'] = get_object_or_404(Bill, pk=bill_id)
+#
+# return context
+#
+#
+# class DenialManagementView(LoginRequiredMixin, PermissionRequiredMixin, CreateProcessView):
+# """
+# View for denial management workflow
+# """
+# model = ClaimDenial
+# form_class = DenialManagementForm
+# template_name = 'billing/denial_management.html'
+# permission_required = 'billing.can_manage_denials'
+# flow_class = DenialManagementFlow
+#
+# def get_form_kwargs(self):
+# kwargs = super().get_form_kwargs()
+# kwargs['tenant'] = self.request.user.tenant
+# return kwargs
+#
+# def form_valid(self, form):
+# with transaction.atomic():
+# # Create denial record
+# denial = form.save(commit=False)
+# denial.tenant = self.request.user.tenant
+# denial.processed_by = self.request.user
+# denial.save()
+#
+# # Update claim status
+# claim = denial.claim
+# claim.status = 'denied'
+# claim.save()
+#
+# # Start denial management workflow
+# process = self.flow_class.start.run(
+# denial=denial,
+# resubmit_claim=form.cleaned_data.get('resubmit_claim', False),
+# file_appeal=form.cleaned_data.get('file_appeal', False),
+# created_by=self.request.user
+# )
+#
+# messages.success(
+# self.request,
+# f'Denial processed for claim {claim.claim_number}. '
+# f'Workflow initiated for corrective actions.'
+# )
+#
+# return redirect('billing:denial_detail', pk=denial.pk)
+#
+# def get_context_data(self, **kwargs):
+# context = super().get_context_data(**kwargs)
+# context['title'] = 'Manage Claim Denial'
+# return context
+#
+#
+# class BillListView(LoginRequiredMixin, PermissionRequiredMixin, ListView):
+# """
+# View for listing bills
+# """
+# model = Bill
+# template_name = 'billing/bill_list.html'
+# context_object_name = 'bills'
+# permission_required = 'billing.view_bill'
+# paginate_by = 25
+#
+# def get_queryset(self):
+# queryset = Bill.objects.filter(tenant=self.request.user.tenant)
+#
+# # Apply filters
+# search = self.request.GET.get('search')
+# if search:
+# queryset = queryset.filter(
+# Q(patient__first_name__icontains=search) |
+# Q(patient__last_name__icontains=search) |
+# Q(bill_number__icontains=search)
+# )
+#
+# status = self.request.GET.get('status')
+# if status:
+# queryset = queryset.filter(status=status)
+#
+# date_from = self.request.GET.get('date_from')
+# if date_from:
+# queryset = queryset.filter(service_date__gte=date_from)
+#
+# date_to = self.request.GET.get('date_to')
+# if date_to:
+# queryset = queryset.filter(service_date__lte=date_to)
+#
+# return queryset.order_by('-created_at')
+#
+# def get_context_data(self, **kwargs):
+# context = super().get_context_data(**kwargs)
+# context['title'] = 'Bills'
+# context['search'] = self.request.GET.get('search', '')
+# context['selected_status'] = self.request.GET.get('status', '')
+# context['date_from'] = self.request.GET.get('date_from', '')
+# context['date_to'] = self.request.GET.get('date_to', '')
+# context['billing_stats'] = self.get_billing_stats()
+# return context
+#
+# def get_billing_stats(self):
+# """Get billing statistics"""
+# bills = Bill.objects.filter(tenant=self.request.user.tenant)
+# return {
+# 'total_bills': bills.count(),
+# 'total_amount': bills.aggregate(Sum('total_amount'))['total_amount__sum'] or 0,
+# 'total_paid': bills.aggregate(Sum('paid_amount'))['paid_amount__sum'] or 0,
+# 'total_outstanding': bills.aggregate(Sum('balance_due'))['balance_due__sum'] or 0
+# }
+#
+#
+# class BillDetailView(LoginRequiredMixin, PermissionRequiredMixin, DetailView):
+# """
+# View for bill details
+# """
+# model = Bill
+# template_name = 'billing/bill_detail.html'
+# context_object_name = 'bill'
+# permission_required = 'billing.view_bill'
+#
+# def get_queryset(self):
+# return Bill.objects.filter(tenant=self.request.user.tenant)
+#
+# def get_context_data(self, **kwargs):
+# context = super().get_context_data(**kwargs)
+# bill = self.object
+# context['title'] = f'Bill {bill.bill_number}'
+# context['items'] = bill.items.all()
+# context['claims'] = bill.claims.all()
+# context['payments'] = bill.payments.all()
+# context['payment_plan'] = getattr(bill, 'payment_plan', None)
+# context['can_edit'] = self.request.user.has_perm('billing.change_bill')
+# context['can_process_payment'] = self.request.user.has_perm('billing.can_process_payments')
+# return context
+#
+#
+# # AJAX Views
+# @login_required
+# @permission_required('billing.view_patient')
+# def patient_billing_search_ajax(request):
+# """AJAX view for patient billing search"""
+# query = request.GET.get('q', '')
+# if len(query) < 2:
+# return JsonResponse({'patients': []})
+#
+# patients = Patient.objects.filter(
+# tenant=request.user.tenant
+# ).filter(
+# Q(first_name__icontains=query) |
+# Q(last_name__icontains=query) |
+# Q(patient_id__icontains=query) |
+# Q(insurance_id__icontains=query)
+# )[:10]
+#
+# patient_data = [
+# {
+# 'id': patient.id,
+# 'name': patient.get_full_name(),
+# 'patient_id': patient.patient_id,
+# 'insurance': patient.primary_insurance.name if patient.primary_insurance else 'No Insurance',
+# 'outstanding_balance': str(patient.get_outstanding_balance())
+# }
+# for patient in patients
+# ]
+#
+# return JsonResponse({'patients': patient_data})
+#
+#
+# @login_required
+# @permission_required('billing.can_calculate_totals')
+# def calculate_bill_totals_ajax(request):
+# """AJAX view to calculate bill totals"""
+# if request.method == 'POST':
+# try:
+# data = json.loads(request.body)
+# items = data.get('items', [])
+#
+# subtotal = Decimal('0.00')
+# for item in items:
+# quantity = Decimal(str(item.get('quantity', 1)))
+# unit_price = Decimal(str(item.get('unit_price', 0)))
+# discount = Decimal(str(item.get('discount', 0)))
+#
+# item_total = (quantity * unit_price) - discount
+# subtotal += item_total
+#
+# tax_rate = Decimal('0.08') # 8% tax rate (configurable)
+# tax_amount = subtotal * tax_rate
+# total_amount = subtotal + tax_amount
+#
+# return JsonResponse({
+# 'success': True,
+# 'subtotal': str(subtotal),
+# 'tax_amount': str(tax_amount),
+# 'total_amount': str(total_amount)
+# })
+# except Exception as e:
+# return JsonResponse({
+# 'success': False,
+# 'error': str(e)
+# })
+#
+# return JsonResponse({'success': False, 'message': 'Invalid request.'})
+#
+#
+# @login_required
+# @permission_required('billing.can_verify_insurance')
+# def verify_insurance_ajax(request, patient_id):
+# """AJAX view to verify insurance"""
+# if request.method == 'POST':
+# try:
+# patient = Patient.objects.get(
+# id=patient_id,
+# tenant=request.user.tenant
+# )
+#
+# # Perform insurance verification
+# verification_result = verify_patient_insurance(patient)
+#
+# return JsonResponse({
+# 'success': verification_result['success'],
+# 'data': verification_result
+# })
+# except Patient.DoesNotExist:
+# return JsonResponse({
+# 'success': False,
+# 'message': 'Patient not found.'
+# })
+#
+# return JsonResponse({'success': False, 'message': 'Invalid request.'})
+#
+#
+# def verify_patient_insurance(patient):
+# """Verify patient insurance"""
+# try:
+# # This would implement actual insurance verification
+# return {
+# 'success': True,
+# 'status': 'active',
+# 'coverage': 'full',
+# 'copay': 25.00,
+# 'deductible': 500.00,
+# 'deductible_met': 150.00,
+# 'out_of_pocket_max': 2000.00,
+# 'out_of_pocket_met': 300.00
+# }
+# except Exception as e:
+# return {
+# 'success': False,
+# 'error': str(e)
+# }
+#
diff --git a/blood_bank/__pycache__/forms.cpython-312.pyc b/blood_bank/__pycache__/forms.cpython-312.pyc
index 9283a135..7690112b 100644
Binary files a/blood_bank/__pycache__/forms.cpython-312.pyc and b/blood_bank/__pycache__/forms.cpython-312.pyc differ
diff --git a/blood_bank/__pycache__/models.cpython-312.pyc b/blood_bank/__pycache__/models.cpython-312.pyc
index 1adafb18..6daed658 100644
Binary files a/blood_bank/__pycache__/models.cpython-312.pyc and b/blood_bank/__pycache__/models.cpython-312.pyc differ
diff --git a/blood_bank/__pycache__/urls.cpython-312.pyc b/blood_bank/__pycache__/urls.cpython-312.pyc
index 0d2a88b5..78ba56aa 100644
Binary files a/blood_bank/__pycache__/urls.cpython-312.pyc and b/blood_bank/__pycache__/urls.cpython-312.pyc differ
diff --git a/blood_bank/__pycache__/views.cpython-312.pyc b/blood_bank/__pycache__/views.cpython-312.pyc
index 6ce82638..c8323144 100644
Binary files a/blood_bank/__pycache__/views.cpython-312.pyc and b/blood_bank/__pycache__/views.cpython-312.pyc differ
diff --git a/blood_bank/models.py b/blood_bank/models.py
index bc0abfc0..9081ba94 100644
--- a/blood_bank/models.py
+++ b/blood_bank/models.py
@@ -3,7 +3,7 @@ from django.db import models
from django.core.validators import MinValueValidator, MaxValueValidator
from django.utils import timezone
from datetime import timedelta
-from core.models import Department
+from hr.models import Department
from patients.models import PatientProfile
from accounts.models import User
diff --git a/blood_bank/urls.py b/blood_bank/urls.py
index 98fa7f5f..fa45fd9e 100644
--- a/blood_bank/urls.py
+++ b/blood_bank/urls.py
@@ -9,25 +9,25 @@ urlpatterns = [
# Donor Management
path('donors/', views.DonorListView.as_view(), name='donor_list'),
- path('donors//', views.donor_detail, name='donor_detail'),
- path('donors/create/', views.donor_create, name='donor_create'),
- path('donors//update/', views.donor_update, name='donor_update'),
+ path('donors//', views.DonorDetailView.as_view(), name='donor_detail'),
+ path('donors/create/', views.DonorCreateView.as_view(), name='donor_create'),
+ path('donors//update/', views.DonorUpdateView.as_view(), name='donor_update'),
path('donors//eligibility/', views.donor_eligibility_check, name='donor_eligibility'),
# Blood Unit Management
- path('units/', views.blood_unit_list, name='blood_unit_list'),
- path('units//', views.blood_unit_detail, name='blood_unit_detail'),
- path('units/create/', views.blood_unit_create, name='blood_unit_create'),
- path('units/create//', views.blood_unit_create, name='blood_unit_create_for_donor'),
+ path('units/', views.BloodUnitListView.as_view(), name='blood_unit_list'),
+ path('units//', views.BloodUnitDetailView.as_view(), name='blood_unit_detail'),
+ path('units/create/', views.BloodUnitCreateView.as_view(), name='blood_unit_create'),
+ path('units/create//', views.BloodUnitCreateView.as_view(), name='blood_unit_create_for_donor'),
# Blood Testing
path('units//test/', views.blood_test_create, name='blood_test_create'),
path('units//crossmatch//', views.crossmatch_create, name='crossmatch_create'),
# Blood Requests
- path('requests/', views.blood_request_list, name='blood_request_list'),
- path('requests//', views.blood_request_detail, name='blood_request_detail'),
- path('requests/create/', views.blood_request_create, name='blood_request_create'),
+ path('requests/', views.BloodRequestListView.as_view(), name='blood_request_list'),
+ path('requests//', views.BloodRequestDetailView.as_view(), name='blood_request_detail'),
+ path('requests/create/', views.BloodRequestCreateView.as_view(), name='blood_request_create'),
# Blood Issue and Transfusion
path('requests//issue/', views.blood_issue_create, name='blood_issue_create'),
diff --git a/blood_bank/views.py b/blood_bank/views.py
index d40f1ba9..3303210e 100644
--- a/blood_bank/views.py
+++ b/blood_bank/views.py
@@ -1,4 +1,4 @@
-from django.contrib.auth.mixins import LoginRequiredMixin
+from django.contrib.auth.mixins import LoginRequiredMixin, PermissionRequiredMixin
from django.shortcuts import render, get_object_or_404, redirect
from django.contrib.auth.decorators import login_required, permission_required
from django.contrib import messages
@@ -11,7 +11,7 @@ from django.contrib.auth.models import User
from datetime import timedelta
import json
-from django.views.generic import ListView
+from django.views.generic import ListView, CreateView, DetailView, DeleteView, UpdateView
from .models import (
BloodGroup, Donor, BloodComponent, BloodUnit, BloodTest, CrossMatch,
@@ -52,9 +52,7 @@ def dashboard(request):
context['blood_group_stats'] = blood_group_stats
# Recent activities
- context['recent_units'] = BloodUnit.objects.select_related(
- 'donor', 'component', 'blood_group'
- ).order_by('-collection_date')[:10]
+ context['recent_units'] = BloodUnit.objects.select_related('donor', 'component', 'blood_group').order_by('-collection_date')
context['urgent_requests'] = BloodRequest.objects.filter(
urgency='emergency', status__in=['pending', 'processing']
@@ -110,62 +108,65 @@ class DonorListView(LoginRequiredMixin, ListView):
-@login_required
-def donor_detail(request, donor_id):
- """Donor detail view with donation history"""
- donor = get_object_or_404(Donor, id=donor_id)
+class DonorDetailView(LoginRequiredMixin, DetailView):
+ model = Donor
+ template_name = 'blood_bank/donors/donor_detail.html'
+ context_object_name = 'donor'
+ pk_url_kwarg = 'donor_id'
- # Get donation history
- blood_units = BloodUnit.objects.filter(donor=donor).select_related(
- 'component', 'blood_group'
- ).order_by('-collection_date')
-
- context = {
- 'donor': donor,
- 'blood_units': blood_units,
- 'total_donations': blood_units.count(),
- 'last_donation': blood_units.first(),
- }
-
- return render(request, 'blood_bank/donors/donor_detail.html', context)
+ def get_context_data(self, **kwargs):
+ ctx = super().get_context_data(**kwargs)
+ donor = self.object
+ blood_units = (
+ BloodUnit.objects
+ .filter(donor=donor)
+ .select_related('component', 'blood_group')
+ .order_by('-collection_date')
+ )
+ ctx.update({
+ 'blood_units': blood_units,
+ 'total_donations': blood_units.count(),
+ 'last_donation': blood_units.first(),
+ })
+ return ctx
-@login_required
-@permission_required('blood_bank.add_donor')
-def donor_create(request):
- """Create new donor"""
- if request.method == 'POST':
- form = DonorForm(request.POST)
- if form.is_valid():
- donor = form.save(commit=False)
- donor.created_by = request.user
- donor.save()
- messages.success(request, f'Donor {donor.donor_id} created successfully.')
- return redirect('blood_bank:donor_detail', donor_id=donor.id)
- else:
- form = DonorForm()
+class DonorCreateView(LoginRequiredMixin, PermissionRequiredMixin, CreateView):
+ model = Donor
+ form_class = DonorForm
+ template_name = 'blood_bank/donors/donor_form.html'
+ permission_required = 'blood_bank.add_donor'
- return render(request, 'blood_bank/donors/donor_form.html', {'form': form, 'title': 'Add New Donor'})
+ def form_valid(self, form):
+ donor = form.save(commit=False)
+ donor.created_by = self.request.user
+ donor.save()
+ messages.success(self.request, f'Donor {donor.donor_id} created successfully.')
+ return redirect('blood_bank:donor_detail', donor_id=donor.id)
+
+ def get_context_data(self, **kwargs):
+ ctx = super().get_context_data(**kwargs)
+ ctx['title'] = 'Add New Donor'
+ return ctx
-@login_required
-@permission_required('blood_bank.change_donor')
-def donor_update(request, donor_id):
- """Update donor information"""
- donor = get_object_or_404(Donor, id=donor_id)
+class DonorUpdateView(LoginRequiredMixin, PermissionRequiredMixin, UpdateView):
+ model = Donor
+ form_class = DonorForm
+ template_name = 'blood_bank/donors/donor_form.html'
+ permission_required = 'blood_bank.change_donor'
+ pk_url_kwarg = 'donor_id'
+ context_object_name = 'donor'
- if request.method == 'POST':
- form = DonorForm(request.POST, instance=donor)
- if form.is_valid():
- form.save()
- messages.success(request, f'Donor {donor.donor_id} updated successfully.')
- return redirect('blood_bank:donor_detail', donor_id=donor.id)
- else:
- form = DonorForm(instance=donor)
+ def form_valid(self, form):
+ donor = form.save()
+ messages.success(self.request, f'Donor {donor.donor_id} updated successfully.')
+ return redirect('blood_bank:donor_detail', donor_id=donor.id)
- return render(request, 'blood_bank/donors/donor_form.html', {
- 'form': form, 'donor': donor, 'title': 'Update Donor'
- })
+ def get_context_data(self, **kwargs):
+ ctx = super().get_context_data(**kwargs)
+ ctx['title'] = 'Update Donor'
+ return ctx
@login_required
@@ -192,167 +193,163 @@ def donor_eligibility_check(request, donor_id):
return render(request, 'blood_bank/donors/donor_eligibility.html', context)
-# Blood Unit Management Views
-@login_required
-def blood_unit_list(request):
- """List all blood units with filtering"""
- form = BloodInventorySearchForm(request.GET)
- blood_units = BloodUnit.objects.select_related(
- 'donor', 'component', 'blood_group'
- ).order_by('-collection_date')
+class BloodUnitListView(LoginRequiredMixin, ListView):
+ model = BloodUnit
+ template_name = 'blood_bank/units/blood_unit_list.html'
+ context_object_name = 'blood_units' # you'll still get page_obj automatically
+ paginate_by = 25
- if form.is_valid():
- if form.cleaned_data['blood_group']:
- blood_units = blood_units.filter(blood_group=form.cleaned_data['blood_group'])
+ def get_queryset(self):
+ # base queryset
+ qs = BloodUnit.objects.select_related('donor', 'component', 'blood_group') \
+ .order_by('-collection_date')
- if form.cleaned_data['component']:
- blood_units = blood_units.filter(component=form.cleaned_data['component'])
+ # bind/validate the filter form
+ self.form = BloodInventorySearchForm(self.request.GET)
+ if self.form.is_valid():
+ cd = self.form.cleaned_data
- if form.cleaned_data['status']:
- blood_units = blood_units.filter(status=form.cleaned_data['status'])
+ if cd.get('blood_group'):
+ qs = qs.filter(blood_group=cd['blood_group'])
- if form.cleaned_data['expiry_days']:
- expiry_date = timezone.now() + timedelta(days=form.cleaned_data['expiry_days'])
- blood_units = blood_units.filter(expiry_date__lte=expiry_date)
+ if cd.get('component'):
+ qs = qs.filter(component=cd['component'])
- paginator = Paginator(blood_units, 25)
- page_number = request.GET.get('page')
- page_obj = paginator.get_page(page_number)
+ if cd.get('status'):
+ qs = qs.filter(status=cd['status'])
- context = {
- 'page_obj': page_obj,
- 'form': form,
- }
+ if cd.get('expiry_days') is not None:
+ expiry_date = timezone.now() + timedelta(days=cd['expiry_days'])
+ qs = qs.filter(expiry_date__lte=expiry_date)
- return render(request, 'blood_bank/units/blood_unit_list.html', context)
+ return qs
+
+ def get_context_data(self, **kwargs):
+ ctx = super().get_context_data(**kwargs)
+ # expose the (bound) form to the template
+ ctx['form'] = getattr(self, 'form', BloodInventorySearchForm(self.request.GET))
+ return ctx
-@login_required
-def blood_unit_detail(request, unit_id):
- """Blood unit detail view with test results"""
- blood_unit = get_object_or_404(BloodUnit, id=unit_id)
+class BloodUnitDetailView(LoginRequiredMixin, DetailView):
+ model = BloodUnit
+ template_name = 'blood_bank/units/blood_unit_detail.html'
+ context_object_name = 'blood_unit'
+ pk_url_kwarg = 'unit_id'
- # Get test results
- tests = BloodTest.objects.filter(blood_unit=blood_unit).select_related('tested_by')
- crossmatches = CrossMatch.objects.filter(blood_unit=blood_unit).select_related(
- 'recipient', 'tested_by'
- )
+ def get_context_data(self, **kwargs):
+ ctx = super().get_context_data(**kwargs)
+ blood_unit = self.object
- context = {
- 'blood_unit': blood_unit,
- 'tests': tests,
- 'crossmatches': crossmatches,
- }
-
- return render(request, 'blood_bank/units/blood_unit_detail.html', context)
+ # related objects
+ ctx['tests'] = BloodTest.objects.filter(blood_unit=blood_unit) \
+ .select_related('tested_by')
+ ctx['crossmatches'] = CrossMatch.objects.filter(blood_unit=blood_unit) \
+ .select_related('recipient', 'tested_by')
+ return ctx
-@login_required
-@permission_required('blood_bank.add_bloodunit')
-def blood_unit_create(request, donor_id=None):
- """Create new blood unit"""
- donor = None
- if donor_id:
- donor = get_object_or_404(Donor, id=donor_id)
+class BloodUnitCreateView(LoginRequiredMixin, PermissionRequiredMixin, CreateView):
+ model = BloodUnit
+ form_class = BloodUnitForm
+ template_name = 'blood_bank/units/blood_unit_form.html'
+ permission_required = 'blood_bank.add_bloodunit'
- if request.method == 'POST':
- form = BloodUnitForm(request.POST)
- if form.is_valid():
- blood_unit = form.save(commit=False)
- blood_unit.collected_by = request.user
- blood_unit.save()
+ def get_initial(self):
+ initial = super().get_initial()
+ donor_id = self.kwargs.get('donor_id')
+ if donor_id:
+ donor = get_object_or_404(Donor, id=donor_id)
+ initial['donor'] = donor
+ initial['blood_group'] = donor.blood_group
+ self.donor = donor # store for use in context
+ return initial
- # Update donor's last donation date and total donations
- if blood_unit.donor:
- blood_unit.donor.last_donation_date = blood_unit.collection_date
- blood_unit.donor.total_donations += 1
- blood_unit.donor.save()
+ def form_valid(self, form):
+ blood_unit = form.save(commit=False)
+ blood_unit.collected_by = self.request.user
+ blood_unit.save()
- messages.success(request, f'Blood unit {blood_unit.unit_number} created successfully.')
- return redirect('blood_bank:blood_unit_detail', unit_id=blood_unit.id)
- else:
- initial_data = {}
- if donor:
- initial_data['donor'] = donor
- initial_data['blood_group'] = donor.blood_group
- form = BloodUnitForm(initial=initial_data)
+ # Update donor’s donation stats
+ if blood_unit.donor:
+ blood_unit.donor.last_donation_date = blood_unit.collection_date
+ blood_unit.donor.total_donations += 1
+ blood_unit.donor.save()
- return render(request, 'blood_bank/units/blood_unit_form.html', {
- 'form': form, 'donor': donor, 'title': 'Register Blood Unit'
- })
+ messages.success(self.request, f'Blood unit {blood_unit.unit_number} created successfully.')
+ return redirect('blood_bank:blood_unit_detail', unit_id=blood_unit.id)
+
+ def get_context_data(self, **kwargs):
+ context = super().get_context_data(**kwargs)
+ context['donor'] = getattr(self, 'donor', None)
+ context['title'] = 'Register Blood Unit'
+ return context
-# Blood Request Management Views
-@login_required
-def blood_request_list(request):
- """List all blood requests"""
- requests = BloodRequest.objects.select_related(
- 'patient', 'requesting_department', 'requesting_physician', 'component_requested'
- ).order_by('-request_date')
+class BloodRequestListView(LoginRequiredMixin, ListView):
+ model = BloodRequest
+ template_name = 'blood_bank/requests/blood_request_list.html'
+ context_object_name = 'page_obj'
+ paginate_by = 25
- # Filter by status
- status_filter = request.GET.get('status')
- if status_filter:
- requests = requests.filter(status=status_filter)
+ def get_queryset(self):
+ qs = BloodRequest.objects.select_related(
+ 'patient', 'requesting_department', 'requesting_physician', 'component_requested'
+ ).order_by('-request_date')
- # Filter by urgency
- urgency_filter = request.GET.get('urgency')
- if urgency_filter:
- requests = requests.filter(urgency=urgency_filter)
+ status_filter = self.request.GET.get('status')
+ urgency_filter = self.request.GET.get('urgency')
- paginator = Paginator(requests, 25)
- page_number = request.GET.get('page')
- page_obj = paginator.get_page(page_number)
+ if status_filter:
+ qs = qs.filter(status=status_filter)
+ if urgency_filter:
+ qs = qs.filter(urgency=urgency_filter)
- context = {
- 'page_obj': page_obj,
- 'status_choices': BloodRequest.STATUS_CHOICES,
- 'urgency_choices': BloodRequest.URGENCY_CHOICES,
- 'status_filter': status_filter,
- 'urgency_filter': urgency_filter,
- }
+ return qs
- return render(request, 'blood_bank/requests/blood_request_list.html', context)
+ def get_context_data(self, **kwargs):
+ context = super().get_context_data(**kwargs)
+ context['status_choices'] = BloodRequest.STATUS_CHOICES
+ context['urgency_choices'] = BloodRequest.URGENCY_CHOICES
+ context['status_filter'] = self.request.GET.get('status')
+ context['urgency_filter'] = self.request.GET.get('urgency')
+ return context
-@login_required
-def blood_request_detail(request, request_id):
- """Blood request detail view"""
- blood_request = get_object_or_404(BloodRequest, id=request_id)
+class BloodRequestDetailView(LoginRequiredMixin, DetailView):
+ model = BloodRequest
+ pk_url_kwarg = 'request_id'
+ template_name = 'blood_bank/requests/blood_request_detail.html'
+ context_object_name = 'blood_request'
- # Get issued units for this request
- issues = BloodIssue.objects.filter(blood_request=blood_request).select_related(
- 'blood_unit', 'issued_by', 'issued_to'
- )
-
- context = {
- 'blood_request': blood_request,
- 'issues': issues,
- }
-
- return render(request, 'blood_bank/requests/blood_request_detail.html', context)
+ def get_context_data(self, **kwargs):
+ context = super().get_context_data(**kwargs)
+ context['issues'] = BloodIssue.objects.filter(
+ blood_request=self.object
+ ).select_related('blood_unit', 'issued_by', 'issued_to')
+ return context
-@login_required
-@permission_required('blood_bank.add_bloodrequest')
-def blood_request_create(request):
- """Create new blood request"""
- if request.method == 'POST':
- form = BloodRequestForm(request.POST)
- if form.is_valid():
- blood_request = form.save(commit=False)
- blood_request.requesting_physician = request.user
- # Generate request number
- blood_request.request_number = f"BR{timezone.now().strftime('%Y%m%d')}{BloodRequest.objects.count() + 1:04d}"
- blood_request.save()
- messages.success(request, f'Blood request {blood_request.request_number} created successfully.')
- return redirect('blood_bank:blood_request_detail', request_id=blood_request.id)
- else:
- form = BloodRequestForm()
+class BloodRequestCreateView(LoginRequiredMixin, PermissionRequiredMixin, CreateView):
+ model = BloodRequest
+ form_class = BloodRequestForm
+ template_name = 'blood_bank/requests/blood_request_form.html'
+ permission_required = 'blood_bank.add_bloodrequest'
- return render(request, 'blood_bank/requests/blood_request_form.html', {
- 'form': form, 'title': 'Create Blood Request'
- })
+ def form_valid(self, form):
+ blood_request = form.save(commit=False)
+ blood_request.requesting_physician = self.request.user
+ # Generate request number
+ blood_request.request_number = f"BR{timezone.now().strftime('%Y%m%d')}{BloodRequest.objects.count() + 1:04d}"
+ blood_request.save()
+
+ messages.success(self.request, f'Blood request {blood_request.request_number} created successfully.')
+ return redirect('blood_bank:blood_request_detail', request_id=blood_request.id)
+
+ def get_context_data(self, **kwargs):
+ context = super().get_context_data(**kwargs)
+ context['title'] = 'Create Blood Request'
+ return context
# Blood Issue and Transfusion Views
diff --git a/communications/__pycache__/flows.cpython-312.pyc b/communications/__pycache__/flows.cpython-312.pyc
new file mode 100644
index 00000000..620ed170
Binary files /dev/null and b/communications/__pycache__/flows.cpython-312.pyc differ
diff --git a/communications/flows.py b/communications/flows.py
new file mode 100644
index 00000000..fc077c27
--- /dev/null
+++ b/communications/flows.py
@@ -0,0 +1,1046 @@
+# """
+# Viewflow workflows for communications app.
+# Provides message routing, notification delivery, and alert management workflows.
+# """
+#
+# from viewflow import Flow, lock
+# from viewflow.base import this, flow_func
+# from viewflow.contrib import celery
+# from viewflow.decorators import flow_view
+# from viewflow.fields import CharField, ModelField
+# from viewflow.forms import ModelForm
+# from viewflow.views import CreateProcessView, UpdateProcessView
+# from viewflow.models import Process, Task
+# from django.contrib.auth.models import User
+# from django.urls import reverse_lazy
+# from django.utils import timezone
+# from django.db import transaction
+# from django.core.mail import send_mail
+#
+# from .models import Message, MessageRecipient, NotificationTemplate, AlertRule, AlertInstance
+# from .views import (
+# MessageCompositionView, RecipientSelectionView, MessageDeliveryView,
+# NotificationCreationView, TemplateSelectionView, AlertConfigurationView,
+# AlertEvaluationView, EscalationView, AcknowledgmentView, ResolutionView
+# )
+#
+#
+# class MessageDeliveryProcess(Process):
+# """
+# Viewflow process model for message delivery
+# """
+# message = ModelField(Message, help_text='Associated message')
+#
+# # Process status tracking
+# message_composed = models.BooleanField(default=False)
+# recipients_selected = models.BooleanField(default=False)
+# content_validated = models.BooleanField(default=False)
+# delivery_scheduled = models.BooleanField(default=False)
+# message_sent = models.BooleanField(default=False)
+# delivery_confirmed = models.BooleanField(default=False)
+# acknowledgments_received = models.BooleanField(default=False)
+# delivery_completed = models.BooleanField(default=False)
+#
+# class Meta:
+# verbose_name = 'Message Delivery Process'
+# verbose_name_plural = 'Message Delivery Processes'
+#
+#
+# class MessageDeliveryFlow(Flow):
+# """
+# Message Delivery Workflow
+#
+# This flow manages message composition, recipient selection,
+# delivery, and acknowledgment tracking.
+# """
+#
+# process_class = MessageDeliveryProcess
+#
+# # Flow definition
+# start = (
+# flow_func(this.start_message_delivery)
+# .Next(this.compose_message)
+# )
+#
+# compose_message = (
+# flow_view(MessageCompositionView)
+# .Permission('communications.can_compose_messages')
+# .Next(this.select_recipients)
+# )
+#
+# select_recipients = (
+# flow_view(RecipientSelectionView)
+# .Permission('communications.can_select_recipients')
+# .Next(this.validate_content)
+# )
+#
+# validate_content = (
+# flow_func(this.perform_content_validation)
+# .Next(this.schedule_delivery)
+# )
+#
+# schedule_delivery = (
+# flow_func(this.setup_delivery_schedule)
+# .Next(this.send_message)
+# )
+#
+# send_message = (
+# flow_view(MessageDeliveryView)
+# .Permission('communications.can_send_messages')
+# .Next(this.confirm_delivery)
+# )
+#
+# confirm_delivery = (
+# flow_func(this.track_delivery_status)
+# .Next(this.collect_acknowledgments)
+# )
+#
+# collect_acknowledgments = (
+# flow_func(this.monitor_acknowledgments)
+# .Next(this.complete_delivery)
+# )
+#
+# complete_delivery = (
+# flow_func(this.finalize_message_delivery)
+# .Next(this.end)
+# )
+#
+# end = flow_func(this.end_message_delivery)
+#
+# # Flow functions
+# def start_message_delivery(self, activation):
+# """Initialize the message delivery process"""
+# process = activation.process
+# message = process.message
+#
+# # Update message status
+# message.status = 'DRAFT'
+# message.save()
+#
+# # Send notification to communications staff
+# self.notify_message_creation(message)
+#
+# # Check for urgent messages
+# if message.priority in ['URGENT', 'CRITICAL'] or message.is_urgent:
+# self.notify_urgent_message(message)
+#
+# def perform_content_validation(self, activation):
+# """Validate message content and compliance"""
+# process = activation.process
+# message = process.message
+#
+# # Perform content validation
+# validation_results = self.validate_message_content(message)
+#
+# if validation_results['is_valid']:
+# process.content_validated = True
+# process.save()
+# else:
+# # Handle validation failures
+# self.handle_validation_failure(message, validation_results)
+#
+# def setup_delivery_schedule(self, activation):
+# """Setup message delivery schedule"""
+# process = activation.process
+# message = process.message
+#
+# # Set delivery schedule
+# if message.scheduled_at:
+# # Message is scheduled for future delivery
+# self.schedule_future_delivery(message)
+# else:
+# # Immediate delivery
+# message.scheduled_at = timezone.now()
+# message.save()
+#
+# # Mark delivery scheduled
+# process.delivery_scheduled = True
+# process.save()
+#
+# def track_delivery_status(self, activation):
+# """Track message delivery status"""
+# process = activation.process
+# message = process.message
+#
+# # Update message status
+# message.status = 'SENT'
+# message.sent_at = timezone.now()
+# message.save()
+#
+# # Mark message sent
+# process.message_sent = True
+# process.save()
+#
+# # Start delivery tracking
+# self.start_delivery_tracking(message)
+#
+# def monitor_acknowledgments(self, activation):
+# """Monitor message acknowledgments"""
+# process = activation.process
+# message = process.message
+#
+# if message.requires_acknowledgment:
+# # Check acknowledgment status
+# acknowledgment_status = self.check_acknowledgment_status(message)
+#
+# if acknowledgment_status['all_acknowledged']:
+# process.acknowledgments_received = True
+# process.save()
+# else:
+# # Send reminders for unacknowledged messages
+# self.send_acknowledgment_reminders(message)
+# else:
+# # No acknowledgment required
+# process.acknowledgments_received = True
+# process.save()
+#
+# def finalize_message_delivery(self, activation):
+# """Finalize the message delivery process"""
+# process = activation.process
+# message = process.message
+#
+# # Update message status
+# message.status = 'DELIVERED'
+# message.save()
+#
+# # Mark process as completed
+# process.delivery_completed = True
+# process.save()
+#
+# # Send completion notifications
+# self.notify_delivery_completion(message)
+#
+# # Update delivery metrics
+# self.update_delivery_metrics(message)
+#
+# def end_message_delivery(self, activation):
+# """End the message delivery workflow"""
+# process = activation.process
+#
+# # Generate delivery summary report
+# self.generate_delivery_summary(process.message)
+#
+# # Helper methods
+# def notify_message_creation(self, message):
+# """Notify communications staff of new message"""
+# from django.contrib.auth.models import Group
+#
+# communications_staff = User.objects.filter(
+# groups__name='Communications Staff'
+# )
+#
+# for staff in communications_staff:
+# send_mail(
+# subject=f'New Message Created: {message.subject}',
+# message=f'New {message.get_message_type_display()} message created by {message.sender.get_full_name()}.',
+# from_email='communications@hospital.com',
+# recipient_list=[staff.email],
+# fail_silently=True
+# )
+#
+# def notify_urgent_message(self, message):
+# """Notify of urgent message"""
+# communications_managers = User.objects.filter(
+# groups__name='Communications Managers'
+# )
+#
+# for manager in communications_managers:
+# send_mail(
+# subject=f'URGENT Message: {message.subject}',
+# message=f'{message.get_priority_display()} message requires immediate attention.',
+# from_email='communications@hospital.com',
+# recipient_list=[manager.email],
+# fail_silently=True
+# )
+#
+# def validate_message_content(self, message):
+# """Validate message content for compliance and quality"""
+# validation_results = {
+# 'is_valid': True,
+# 'errors': [],
+# 'warnings': []
+# }
+#
+# # Content validation logic would go here
+# # Check for compliance, appropriate language, etc.
+#
+# return validation_results
+#
+# def handle_validation_failure(self, message, validation_results):
+# """Handle message validation failures"""
+# # This would handle validation failures
+# pass
+#
+# def schedule_future_delivery(self, message):
+# """Schedule message for future delivery"""
+# # Schedule delivery task
+# send_scheduled_message.apply_async(
+# args=[message.message_id],
+# eta=message.scheduled_at
+# )
+#
+# def start_delivery_tracking(self, message):
+# """Start tracking message delivery"""
+# # This would start delivery tracking for all recipients
+# pass
+#
+# def check_acknowledgment_status(self, message):
+# """Check acknowledgment status for all recipients"""
+# recipients = message.recipients.all()
+# total_recipients = recipients.count()
+# acknowledged_recipients = recipients.filter(status='ACKNOWLEDGED').count()
+#
+# return {
+# 'all_acknowledged': acknowledged_recipients == total_recipients,
+# 'acknowledgment_rate': acknowledged_recipients / total_recipients if total_recipients > 0 else 0
+# }
+#
+# def send_acknowledgment_reminders(self, message):
+# """Send reminders for unacknowledged messages"""
+# unacknowledged_recipients = message.recipients.filter(
+# status__in=['DELIVERED', 'READ']
+# )
+#
+# for recipient in unacknowledged_recipients:
+# self.send_acknowledgment_reminder(recipient)
+#
+# def send_acknowledgment_reminder(self, recipient):
+# """Send acknowledgment reminder to specific recipient"""
+# # This would send reminder to recipient
+# pass
+#
+# def notify_delivery_completion(self, message):
+# """Notify delivery completion"""
+# # Notify sender
+# if message.sender and message.sender.email:
+# send_mail(
+# subject=f'Message Delivered: {message.subject}',
+# message=f'Your message has been successfully delivered to all recipients.',
+# from_email='communications@hospital.com',
+# recipient_list=[message.sender.email],
+# fail_silently=True
+# )
+#
+# def update_delivery_metrics(self, message):
+# """Update message delivery metrics"""
+# # This would update delivery performance metrics
+# pass
+#
+# def generate_delivery_summary(self, message):
+# """Generate message delivery summary"""
+# # This would generate comprehensive delivery report
+# pass
+#
+#
+# class NotificationManagementProcess(Process):
+# """
+# Viewflow process model for notification management
+# """
+# notification_template = ModelField(NotificationTemplate, help_text='Associated notification template')
+#
+# # Process status tracking
+# template_selected = models.BooleanField(default=False)
+# content_generated = models.BooleanField(default=False)
+# recipients_determined = models.BooleanField(default=False)
+# notifications_created = models.BooleanField(default=False)
+# delivery_initiated = models.BooleanField(default=False)
+# delivery_monitored = models.BooleanField(default=False)
+# notifications_completed = models.BooleanField(default=False)
+#
+# class Meta:
+# verbose_name = 'Notification Management Process'
+# verbose_name_plural = 'Notification Management Processes'
+#
+#
+# class NotificationManagementFlow(Flow):
+# """
+# Notification Management Workflow
+#
+# This flow manages automated notification generation,
+# delivery, and tracking using templates.
+# """
+#
+# process_class = NotificationManagementProcess
+#
+# # Flow definition
+# start = (
+# flow_func(this.start_notification_management)
+# .Next(this.select_template)
+# )
+#
+# select_template = (
+# flow_view(TemplateSelectionView)
+# .Permission('communications.can_select_templates')
+# .Next(this.generate_content)
+# )
+#
+# generate_content = (
+# flow_func(this.create_notification_content)
+# .Next(this.determine_recipients)
+# )
+#
+# determine_recipients = (
+# flow_func(this.identify_notification_recipients)
+# .Next(this.create_notifications)
+# )
+#
+# create_notifications = (
+# flow_view(NotificationCreationView)
+# .Permission('communications.can_create_notifications')
+# .Next(this.initiate_delivery)
+# )
+#
+# initiate_delivery = (
+# flow_func(this.start_notification_delivery)
+# .Next(this.monitor_delivery)
+# )
+#
+# monitor_delivery = (
+# flow_func(this.track_notification_delivery)
+# .Next(this.complete_notifications)
+# )
+#
+# complete_notifications = (
+# flow_func(this.finalize_notification_management)
+# .Next(this.end)
+# )
+#
+# end = flow_func(this.end_notification_management)
+#
+# # Flow functions
+# def start_notification_management(self, activation):
+# """Initialize the notification management process"""
+# process = activation.process
+# template = process.notification_template
+#
+# # Send notification to communications staff
+# self.notify_notification_triggered(template)
+#
+# def create_notification_content(self, activation):
+# """Generate notification content from template"""
+# process = activation.process
+# template = process.notification_template
+#
+# # Generate content using template
+# content = self.generate_template_content(template)
+#
+# # Mark content generated
+# process.content_generated = True
+# process.save()
+#
+# # Store generated content
+# self.store_generated_content(template, content)
+#
+# def identify_notification_recipients(self, activation):
+# """Identify notification recipients"""
+# process = activation.process
+# template = process.notification_template
+#
+# # Determine recipients based on template configuration
+# recipients = self.determine_template_recipients(template)
+#
+# # Mark recipients determined
+# process.recipients_determined = True
+# process.save()
+#
+# # Store recipient list
+# self.store_recipient_list(template, recipients)
+#
+# def start_notification_delivery(self, activation):
+# """Start notification delivery"""
+# process = activation.process
+# template = process.notification_template
+#
+# # Initiate delivery for all notifications
+# self.initiate_template_delivery(template)
+#
+# # Mark delivery initiated
+# process.delivery_initiated = True
+# process.save()
+#
+# def track_notification_delivery(self, activation):
+# """Track notification delivery progress"""
+# process = activation.process
+# template = process.notification_template
+#
+# # Monitor delivery status
+# delivery_status = self.monitor_template_delivery(template)
+#
+# if delivery_status['all_delivered']:
+# process.delivery_monitored = True
+# process.save()
+# else:
+# # Continue monitoring
+# self.schedule_delivery_monitoring(template)
+#
+# def finalize_notification_management(self, activation):
+# """Finalize the notification management process"""
+# process = activation.process
+# template = process.notification_template
+#
+# # Mark process as completed
+# process.notifications_completed = True
+# process.save()
+#
+# # Update template usage statistics
+# self.update_template_usage(template)
+#
+# # Send completion notifications
+# self.notify_notification_completion(template)
+#
+# def end_notification_management(self, activation):
+# """End the notification management workflow"""
+# process = activation.process
+#
+# # Generate notification summary
+# self.generate_notification_summary(process.notification_template)
+#
+# # Helper methods
+# def notify_notification_triggered(self, template):
+# """Notify communications staff of triggered notification"""
+# communications_staff = User.objects.filter(
+# groups__name='Communications Staff'
+# )
+#
+# for staff in communications_staff:
+# send_mail(
+# subject=f'Notification Triggered: {template.name}',
+# message=f'Automated notification "{template.name}" has been triggered.',
+# from_email='notifications@hospital.com',
+# recipient_list=[staff.email],
+# fail_silently=True
+# )
+#
+# def generate_template_content(self, template):
+# """Generate content from notification template"""
+# # This would implement template rendering logic
+# return {
+# 'subject': template.subject_template,
+# 'content': template.content_template
+# }
+#
+# def store_generated_content(self, template, content):
+# """Store generated notification content"""
+# # This would store the generated content
+# pass
+#
+# def determine_template_recipients(self, template):
+# """Determine recipients for template notifications"""
+# # This would implement recipient determination logic
+# return []
+#
+# def store_recipient_list(self, template, recipients):
+# """Store recipient list for template"""
+# # This would store the recipient list
+# pass
+#
+# def initiate_template_delivery(self, template):
+# """Initiate delivery for template notifications"""
+# # This would start delivery for all notifications
+# pass
+#
+# def monitor_template_delivery(self, template):
+# """Monitor template notification delivery"""
+# # This would monitor delivery progress
+# return {'all_delivered': True}
+#
+# def schedule_delivery_monitoring(self, template):
+# """Schedule continued delivery monitoring"""
+# # This would schedule monitoring tasks
+# pass
+#
+# def update_template_usage(self, template):
+# """Update template usage statistics"""
+# template.usage_count += 1
+# template.last_used_at = timezone.now()
+# template.save()
+#
+# def notify_notification_completion(self, template):
+# """Notify notification completion"""
+# # This would notify relevant parties
+# pass
+#
+# def generate_notification_summary(self, template):
+# """Generate notification summary"""
+# # This would generate notification summary
+# pass
+#
+#
+# class AlertManagementProcess(Process):
+# """
+# Viewflow process model for alert management
+# """
+# alert_instance = ModelField(AlertInstance, help_text='Associated alert instance')
+#
+# # Process status tracking
+# alert_triggered = models.BooleanField(default=False)
+# alert_evaluated = models.BooleanField(default=False)
+# notifications_sent = models.BooleanField(default=False)
+# acknowledgment_received = models.BooleanField(default=False)
+# escalation_processed = models.BooleanField(default=False)
+# resolution_completed = models.BooleanField(default=False)
+# alert_closed = models.BooleanField(default=False)
+#
+# class Meta:
+# verbose_name = 'Alert Management Process'
+# verbose_name_plural = 'Alert Management Processes'
+#
+#
+# class AlertManagementFlow(Flow):
+# """
+# Alert Management Workflow
+#
+# This flow manages alert lifecycle from trigger through
+# acknowledgment, escalation, and resolution.
+# """
+#
+# process_class = AlertManagementProcess
+#
+# # Flow definition
+# start = (
+# flow_func(this.start_alert_management)
+# .Next(this.trigger_alert)
+# )
+#
+# trigger_alert = (
+# flow_func(this.process_alert_trigger)
+# .Next(this.evaluate_alert)
+# )
+#
+# evaluate_alert = (
+# flow_view(AlertEvaluationView)
+# .Permission('communications.can_evaluate_alerts')
+# .Next(this.send_notifications)
+# )
+#
+# send_notifications = (
+# flow_func(this.dispatch_alert_notifications)
+# .Next(this.await_acknowledgment)
+# )
+#
+# await_acknowledgment = (
+# flow_view(AcknowledgmentView)
+# .Permission('communications.can_acknowledge_alerts')
+# .Next(this.process_escalation)
+# )
+#
+# process_escalation = (
+# flow_view(EscalationView)
+# .Permission('communications.can_escalate_alerts')
+# .Next(this.resolve_alert)
+# )
+#
+# resolve_alert = (
+# flow_view(ResolutionView)
+# .Permission('communications.can_resolve_alerts')
+# .Next(this.close_alert)
+# )
+#
+# close_alert = (
+# flow_func(this.finalize_alert_management)
+# .Next(this.end)
+# )
+#
+# end = flow_func(this.end_alert_management)
+#
+# # Flow functions
+# def start_alert_management(self, activation):
+# """Initialize the alert management process"""
+# process = activation.process
+# alert = process.alert_instance
+#
+# # Update alert status
+# alert.status = 'ACTIVE'
+# alert.save()
+#
+# # Send immediate notifications for critical alerts
+# if alert.severity in ['CRITICAL', 'EMERGENCY']:
+# self.send_immediate_notifications(alert)
+#
+# def process_alert_trigger(self, activation):
+# """Process alert trigger conditions"""
+# process = activation.process
+# alert = process.alert_instance
+#
+# # Mark alert as triggered
+# process.alert_triggered = True
+# process.save()
+#
+# # Log alert trigger
+# self.log_alert_trigger(alert)
+#
+# # Check for duplicate alerts
+# self.check_duplicate_alerts(alert)
+#
+# def dispatch_alert_notifications(self, activation):
+# """Dispatch alert notifications"""
+# process = activation.process
+# alert = process.alert_instance
+#
+# # Send notifications to configured recipients
+# self.send_alert_notifications(alert)
+#
+# # Mark notifications sent
+# process.notifications_sent = True
+# process.save()
+#
+# # Schedule escalation if no acknowledgment
+# self.schedule_escalation(alert)
+#
+# def finalize_alert_management(self, activation):
+# """Finalize the alert management process"""
+# process = activation.process
+# alert = process.alert_instance
+#
+# # Update alert status
+# alert.status = 'RESOLVED'
+# alert.resolved_at = timezone.now()
+# alert.save()
+#
+# # Mark process as completed
+# process.alert_closed = True
+# process.save()
+#
+# # Send resolution notifications
+# self.notify_alert_resolution(alert)
+#
+# # Update alert metrics
+# self.update_alert_metrics(alert)
+#
+# def end_alert_management(self, activation):
+# """End the alert management workflow"""
+# process = activation.process
+#
+# # Generate alert summary
+# self.generate_alert_summary(process.alert_instance)
+#
+# # Helper methods
+# def send_immediate_notifications(self, alert):
+# """Send immediate notifications for critical alerts"""
+# # This would send immediate notifications
+# pass
+#
+# def log_alert_trigger(self, alert):
+# """Log alert trigger event"""
+# # This would log the alert trigger
+# pass
+#
+# def check_duplicate_alerts(self, alert):
+# """Check for duplicate alerts"""
+# # This would check for and handle duplicate alerts
+# pass
+#
+# def send_alert_notifications(self, alert):
+# """Send alert notifications to recipients"""
+# rule = alert.alert_rule
+#
+# # Send to default recipients
+# for recipient in rule.default_recipients.all():
+# self.send_alert_to_recipient(alert, recipient)
+#
+# # Send to role-based recipients
+# for role in rule.recipient_roles:
+# role_recipients = User.objects.filter(groups__name=role)
+# for recipient in role_recipients:
+# self.send_alert_to_recipient(alert, recipient)
+#
+# def send_alert_to_recipient(self, alert, recipient):
+# """Send alert to specific recipient"""
+# if recipient.email:
+# send_mail(
+# subject=f'ALERT: {alert.title}',
+# message=f'Alert: {alert.description}\nSeverity: {alert.severity}',
+# from_email='alerts@hospital.com',
+# recipient_list=[recipient.email],
+# fail_silently=True
+# )
+#
+# def schedule_escalation(self, alert):
+# """Schedule alert escalation"""
+# rule = alert.alert_rule
+# escalation_rules = rule.escalation_rules
+#
+# if escalation_rules:
+# # Schedule escalation task
+# escalate_alert.apply_async(
+# args=[alert.alert_id],
+# countdown=escalation_rules.get('escalation_delay', 3600) # 1 hour default
+# )
+#
+# def notify_alert_resolution(self, alert):
+# """Notify alert resolution"""
+# # Notify all recipients of resolution
+# rule = alert.alert_rule
+#
+# for recipient in rule.default_recipients.all():
+# if recipient.email:
+# send_mail(
+# subject=f'RESOLVED: {alert.title}',
+# message=f'Alert has been resolved: {alert.description}',
+# from_email='alerts@hospital.com',
+# recipient_list=[recipient.email],
+# fail_silently=True
+# )
+#
+# def update_alert_metrics(self, alert):
+# """Update alert performance metrics"""
+# # This would update alert metrics
+# pass
+#
+# def generate_alert_summary(self, alert):
+# """Generate alert summary"""
+# # This would generate alert summary
+# pass
+#
+#
+# class CommunicationAuditProcess(Process):
+# """
+# Viewflow process model for communication audit
+# """
+# audit_period_start = models.DateTimeField(help_text='Audit period start')
+# audit_period_end = models.DateTimeField(help_text='Audit period end')
+#
+# # Process status tracking
+# audit_initiated = models.BooleanField(default=False)
+# data_collected = models.BooleanField(default=False)
+# analysis_completed = models.BooleanField(default=False)
+# report_generated = models.BooleanField(default=False)
+# audit_completed = models.BooleanField(default=False)
+#
+# class Meta:
+# verbose_name = 'Communication Audit Process'
+# verbose_name_plural = 'Communication Audit Processes'
+#
+#
+# class CommunicationAuditFlow(Flow):
+# """
+# Communication Audit Workflow
+#
+# This flow manages communication auditing including
+# data collection, analysis, and reporting.
+# """
+#
+# process_class = CommunicationAuditProcess
+#
+# # Flow definition
+# start = (
+# flow_func(this.start_communication_audit)
+# .Next(this.initiate_audit)
+# )
+#
+# initiate_audit = (
+# flow_func(this.setup_audit_parameters)
+# .Next(this.collect_data)
+# )
+#
+# collect_data = (
+# flow_func(this.gather_communication_data)
+# .Next(this.analyze_data)
+# )
+#
+# analyze_data = (
+# flow_func(this.perform_communication_analysis)
+# .Next(this.generate_report)
+# )
+#
+# generate_report = (
+# flow_func(this.create_audit_report)
+# .Next(this.complete_audit)
+# )
+#
+# complete_audit = (
+# flow_func(this.finalize_communication_audit)
+# .Next(this.end)
+# )
+#
+# end = flow_func(this.end_communication_audit)
+#
+# # Flow functions
+# def start_communication_audit(self, activation):
+# """Initialize the communication audit process"""
+# process = activation.process
+#
+# # Send audit notification
+# self.notify_audit_start(process.audit_period_start, process.audit_period_end)
+#
+# def setup_audit_parameters(self, activation):
+# """Setup audit parameters and scope"""
+# process = activation.process
+#
+# # Mark audit initiated
+# process.audit_initiated = True
+# process.save()
+#
+# # Configure audit parameters
+# self.configure_audit_scope(process.audit_period_start, process.audit_period_end)
+#
+# def gather_communication_data(self, activation):
+# """Gather communication data for audit"""
+# process = activation.process
+#
+# # Collect communication data
+# self.collect_audit_data(process.audit_period_start, process.audit_period_end)
+#
+# # Mark data collected
+# process.data_collected = True
+# process.save()
+#
+# def perform_communication_analysis(self, activation):
+# """Perform communication analysis"""
+# process = activation.process
+#
+# # Analyze communication patterns and compliance
+# self.analyze_communication_patterns(process.audit_period_start, process.audit_period_end)
+#
+# # Mark analysis completed
+# process.analysis_completed = True
+# process.save()
+#
+# def create_audit_report(self, activation):
+# """Create audit report"""
+# process = activation.process
+#
+# # Generate comprehensive audit report
+# self.generate_audit_report(process.audit_period_start, process.audit_period_end)
+#
+# # Mark report generated
+# process.report_generated = True
+# process.save()
+#
+# def finalize_communication_audit(self, activation):
+# """Finalize the communication audit process"""
+# process = activation.process
+#
+# # Mark audit completed
+# process.audit_completed = True
+# process.save()
+#
+# # Send audit completion notification
+# self.notify_audit_completion(process.audit_period_start, process.audit_period_end)
+#
+# def end_communication_audit(self, activation):
+# """End the communication audit workflow"""
+# process = activation.process
+#
+# # Archive audit results
+# self.archive_audit_results(process.audit_period_start, process.audit_period_end)
+#
+# # Helper methods
+# def notify_audit_start(self, start_date, end_date):
+# """Notify audit start"""
+# # This would notify relevant parties of audit start
+# pass
+#
+# def configure_audit_scope(self, start_date, end_date):
+# """Configure audit scope and parameters"""
+# # This would configure audit parameters
+# pass
+#
+# def collect_audit_data(self, start_date, end_date):
+# """Collect communication data for audit"""
+# # This would collect all relevant communication data
+# pass
+#
+# def analyze_communication_patterns(self, start_date, end_date):
+# """Analyze communication patterns"""
+# # This would analyze communication effectiveness and compliance
+# pass
+#
+# def generate_audit_report(self, start_date, end_date):
+# """Generate comprehensive audit report"""
+# # This would generate detailed audit report
+# pass
+#
+# def notify_audit_completion(self, start_date, end_date):
+# """Notify audit completion"""
+# # This would notify audit completion
+# pass
+#
+# def archive_audit_results(self, start_date, end_date):
+# """Archive audit results"""
+# # This would archive audit results for future reference
+# pass
+#
+#
+# # Celery tasks for background processing
+# @celery.job
+# def send_scheduled_message(message_id):
+# """Background task to send scheduled messages"""
+# try:
+# message = Message.objects.get(message_id=message_id)
+#
+# # Send message to all recipients
+# for recipient in message.recipients.all():
+# send_message_to_recipient(message, recipient)
+#
+# # Update message status
+# message.status = 'SENT'
+# message.sent_at = timezone.now()
+# message.save()
+#
+# return True
+# except Exception:
+# return False
+#
+#
+# @celery.job
+# def escalate_alert(alert_id):
+# """Background task to escalate alerts"""
+# try:
+# alert = AlertInstance.objects.get(alert_id=alert_id)
+#
+# if alert.status == 'ACTIVE':
+# # Escalate alert
+# alert.escalation_level += 1
+# alert.escalated_at = timezone.now()
+# alert.save()
+#
+# # Send escalation notifications
+# send_escalation_notifications(alert)
+#
+# return True
+# except Exception:
+# return False
+#
+#
+# @celery.job
+# def process_notification_queue():
+# """Background task to process notification queue"""
+# try:
+# # This would process pending notifications
+# return True
+# except Exception:
+# return False
+#
+#
+# @celery.job
+# def cleanup_expired_messages():
+# """Background task to cleanup expired messages"""
+# try:
+# # This would cleanup expired messages
+# return True
+# except Exception:
+# return False
+#
+#
+# @celery.job
+# def generate_communication_reports():
+# """Background task to generate communication reports"""
+# try:
+# # This would generate periodic communication reports
+# return True
+# except Exception:
+# return False
+#
+#
+# def send_message_to_recipient(message, recipient):
+# """Helper function to send message to specific recipient"""
+# # This would implement actual message sending logic
+# pass
+#
+#
+# def send_escalation_notifications(alert):
+# """Helper function to send escalation notifications"""
+# # This would send escalation notifications
+# pass
+#
diff --git a/core/__pycache__/admin.cpython-312.pyc b/core/__pycache__/admin.cpython-312.pyc
index cf8a7ffc..00b2aa28 100644
Binary files a/core/__pycache__/admin.cpython-312.pyc and b/core/__pycache__/admin.cpython-312.pyc differ
diff --git a/core/__pycache__/flows.cpython-312.pyc b/core/__pycache__/flows.cpython-312.pyc
new file mode 100644
index 00000000..aadce5c4
Binary files /dev/null and b/core/__pycache__/flows.cpython-312.pyc differ
diff --git a/core/__pycache__/forms.cpython-312.pyc b/core/__pycache__/forms.cpython-312.pyc
index 13ebdd6d..2b335ed8 100644
Binary files a/core/__pycache__/forms.cpython-312.pyc and b/core/__pycache__/forms.cpython-312.pyc differ
diff --git a/core/__pycache__/models.cpython-312.pyc b/core/__pycache__/models.cpython-312.pyc
index a41f847e..01ccffd0 100644
Binary files a/core/__pycache__/models.cpython-312.pyc and b/core/__pycache__/models.cpython-312.pyc differ
diff --git a/core/__pycache__/views.cpython-312.pyc b/core/__pycache__/views.cpython-312.pyc
index aff523a8..c4cf615b 100644
Binary files a/core/__pycache__/views.cpython-312.pyc and b/core/__pycache__/views.cpython-312.pyc differ
diff --git a/core/flows.py b/core/flows.py
new file mode 100644
index 00000000..4e05b8d3
--- /dev/null
+++ b/core/flows.py
@@ -0,0 +1,849 @@
+# """
+# Viewflow workflows for core app.
+# Provides system administration, tenant management, and configuration workflows.
+# """
+#
+# from viewflow import Flow, lock
+# from viewflow.base import this, flow_func
+# from viewflow.contrib import celery
+# from viewflow.decorators import flow_view
+# from viewflow.fields import CharField, ModelField
+# from viewflow.forms import ModelForm
+# from viewflow.views import CreateProcessView, UpdateProcessView
+# from viewflow.models import Process, Task
+# from django.contrib.auth.models import User
+# from django.urls import reverse_lazy
+# from django.utils import timezone
+# from django.db import transaction
+# from django.core.mail import send_mail
+#
+# from .models import Tenant, Department, AuditLogEntry, SystemConfiguration, SystemNotification, IntegrationLog
+# from .views import (
+# TenantSetupView, DepartmentManagementView, ConfigurationView,
+# AuditReviewView, NotificationManagementView, IntegrationMonitoringView,
+# SystemMaintenanceView, BackupView, SecurityAuditView, ComplianceCheckView
+# )
+#
+#
+# class TenantOnboardingProcess(Process):
+# """
+# Viewflow process model for tenant onboarding
+# """
+# tenant = ModelField(Tenant, help_text='Associated tenant')
+#
+# # Process status tracking
+# tenant_created = models.BooleanField(default=False)
+# configuration_setup = models.BooleanField(default=False)
+# departments_created = models.BooleanField(default=False)
+# users_configured = models.BooleanField(default=False)
+# integrations_setup = models.BooleanField(default=False)
+# testing_completed = models.BooleanField(default=False)
+# training_provided = models.BooleanField(default=False)
+# onboarding_completed = models.BooleanField(default=False)
+#
+# class Meta:
+# verbose_name = 'Tenant Onboarding Process'
+# verbose_name_plural = 'Tenant Onboarding Processes'
+#
+#
+# class TenantOnboardingFlow(Flow):
+# """
+# Tenant Onboarding Workflow
+#
+# This flow manages complete tenant onboarding from initial
+# setup through configuration, testing, and go-live.
+# """
+#
+# process_class = TenantOnboardingProcess
+#
+# # Flow definition
+# start = (
+# flow_func(this.start_tenant_onboarding)
+# .Next(this.setup_tenant)
+# )
+#
+# setup_tenant = (
+# flow_view(TenantSetupView)
+# .Permission('core.can_setup_tenants')
+# .Next(this.configure_system)
+# )
+#
+# configure_system = (
+# flow_view(ConfigurationView)
+# .Permission('core.can_configure_system')
+# .Next(this.create_departments)
+# )
+#
+# create_departments = (
+# flow_view(DepartmentManagementView)
+# .Permission('core.can_manage_departments')
+# .Next(this.configure_users)
+# )
+#
+# configure_users = (
+# flow_func(this.setup_initial_users)
+# .Next(this.setup_integrations)
+# )
+#
+# setup_integrations = (
+# flow_func(this.configure_integrations)
+# .Next(this.complete_testing)
+# )
+#
+# complete_testing = (
+# flow_func(this.perform_system_testing)
+# .Next(this.provide_training)
+# )
+#
+# provide_training = (
+# flow_func(this.deliver_user_training)
+# .Next(this.finalize_onboarding)
+# )
+#
+# finalize_onboarding = (
+# flow_func(this.complete_tenant_onboarding)
+# .Next(this.end)
+# )
+#
+# end = flow_func(this.end_tenant_onboarding)
+#
+# # Flow functions
+# def start_tenant_onboarding(self, activation):
+# """Initialize the tenant onboarding process"""
+# process = activation.process
+# tenant = process.tenant
+#
+# # Send onboarding notification
+# self.notify_onboarding_start(tenant)
+#
+# # Create onboarding checklist
+# self.create_onboarding_checklist(tenant)
+#
+# # Set up audit logging
+# self.setup_audit_logging(tenant)
+#
+# def setup_initial_users(self, activation):
+# """Setup initial users for tenant"""
+# process = activation.process
+# tenant = process.tenant
+#
+# # Create initial admin users
+# self.create_admin_users(tenant)
+#
+# # Mark users configured
+# process.users_configured = True
+# process.save()
+#
+# # Send user credentials
+# self.send_user_credentials(tenant)
+#
+# def configure_integrations(self, activation):
+# """Configure system integrations"""
+# process = activation.process
+# tenant = process.tenant
+#
+# # Setup default integrations
+# self.setup_default_integrations(tenant)
+#
+# # Mark integrations setup
+# process.integrations_setup = True
+# process.save()
+#
+# # Test integration connectivity
+# self.test_integration_connectivity(tenant)
+#
+# def perform_system_testing(self, activation):
+# """Perform comprehensive system testing"""
+# process = activation.process
+# tenant = process.tenant
+#
+# # Execute system tests
+# test_results = self.execute_system_tests(tenant)
+#
+# # Mark testing completed
+# process.testing_completed = True
+# process.save()
+#
+# # Store test results
+# self.store_test_results(tenant, test_results)
+#
+# def deliver_user_training(self, activation):
+# """Deliver user training"""
+# process = activation.process
+# tenant = process.tenant
+#
+# # Schedule training sessions
+# self.schedule_training_sessions(tenant)
+#
+# # Mark training provided
+# process.training_provided = True
+# process.save()
+#
+# # Send training materials
+# self.send_training_materials(tenant)
+#
+# def complete_tenant_onboarding(self, activation):
+# """Complete the tenant onboarding process"""
+# process = activation.process
+# tenant = process.tenant
+#
+# # Activate tenant
+# tenant.is_active = True
+# tenant.save()
+#
+# # Mark onboarding completed
+# process.onboarding_completed = True
+# process.save()
+#
+# # Send completion notifications
+# self.notify_onboarding_completion(tenant)
+#
+# # Schedule post-onboarding follow-up
+# self.schedule_followup(tenant)
+#
+# def end_tenant_onboarding(self, activation):
+# """End the tenant onboarding workflow"""
+# process = activation.process
+#
+# # Generate onboarding summary
+# self.generate_onboarding_summary(process.tenant)
+#
+# # Helper methods
+# def notify_onboarding_start(self, tenant):
+# """Notify onboarding start"""
+# admin_team = User.objects.filter(groups__name='System Administrators')
+# for admin in admin_team:
+# send_mail(
+# subject=f'Tenant Onboarding Started: {tenant.name}',
+# message=f'Onboarding process started for tenant "{tenant.name}".',
+# from_email='admin@hospital.com',
+# recipient_list=[admin.email],
+# fail_silently=True
+# )
+#
+# def create_onboarding_checklist(self, tenant):
+# """Create onboarding checklist"""
+# # This would create a comprehensive onboarding checklist
+# pass
+#
+# def setup_audit_logging(self, tenant):
+# """Setup audit logging for tenant"""
+# # This would configure audit logging
+# pass
+#
+# def create_admin_users(self, tenant):
+# """Create initial admin users"""
+# # This would create initial admin users
+# pass
+#
+# def send_user_credentials(self, tenant):
+# """Send user credentials"""
+# # This would send initial user credentials
+# pass
+#
+# def setup_default_integrations(self, tenant):
+# """Setup default integrations"""
+# # This would configure default integrations
+# pass
+#
+# def test_integration_connectivity(self, tenant):
+# """Test integration connectivity"""
+# # This would test all integrations
+# pass
+#
+# def execute_system_tests(self, tenant):
+# """Execute comprehensive system tests"""
+# # This would run system tests
+# return {'status': 'passed', 'issues': []}
+#
+# def store_test_results(self, tenant, results):
+# """Store test results"""
+# # This would store test results
+# pass
+#
+# def schedule_training_sessions(self, tenant):
+# """Schedule training sessions"""
+# # This would schedule training
+# pass
+#
+# def send_training_materials(self, tenant):
+# """Send training materials"""
+# # This would send training materials
+# pass
+#
+# def notify_onboarding_completion(self, tenant):
+# """Notify onboarding completion"""
+# send_mail(
+# subject=f'Tenant Onboarding Complete: {tenant.name}',
+# message=f'Onboarding completed successfully for "{tenant.name}".',
+# from_email='admin@hospital.com',
+# recipient_list=[tenant.email],
+# fail_silently=True
+# )
+#
+# def schedule_followup(self, tenant):
+# """Schedule post-onboarding follow-up"""
+# # Schedule follow-up task
+# tenant_followup.apply_async(
+# args=[tenant.tenant_id],
+# countdown=86400 * 7 # 7 days
+# )
+#
+# def generate_onboarding_summary(self, tenant):
+# """Generate onboarding summary"""
+# # This would generate onboarding summary
+# pass
+#
+#
+# class SystemMaintenanceProcess(Process):
+# """
+# Viewflow process model for system maintenance
+# """
+# maintenance_type = models.CharField(max_length=50, help_text='Type of maintenance')
+#
+# # Process status tracking
+# maintenance_scheduled = models.BooleanField(default=False)
+# notifications_sent = models.BooleanField(default=False)
+# backup_completed = models.BooleanField(default=False)
+# maintenance_executed = models.BooleanField(default=False)
+# testing_completed = models.BooleanField(default=False)
+# system_restored = models.BooleanField(default=False)
+# maintenance_completed = models.BooleanField(default=False)
+#
+# class Meta:
+# verbose_name = 'System Maintenance Process'
+# verbose_name_plural = 'System Maintenance Processes'
+#
+#
+# class SystemMaintenanceFlow(Flow):
+# """
+# System Maintenance Workflow
+#
+# This flow manages scheduled system maintenance including
+# notifications, backups, execution, and restoration.
+# """
+#
+# process_class = SystemMaintenanceProcess
+#
+# # Flow definition
+# start = (
+# flow_func(this.start_system_maintenance)
+# .Next(this.schedule_maintenance)
+# )
+#
+# schedule_maintenance = (
+# flow_view(SystemMaintenanceView)
+# .Permission('core.can_schedule_maintenance')
+# .Next(this.send_notifications)
+# )
+#
+# send_notifications = (
+# flow_func(this.notify_maintenance_window)
+# .Next(this.create_backup)
+# )
+#
+# create_backup = (
+# flow_view(BackupView)
+# .Permission('core.can_create_backups')
+# .Next(this.execute_maintenance)
+# )
+#
+# execute_maintenance = (
+# flow_func(this.perform_maintenance_tasks)
+# .Next(this.test_system)
+# )
+#
+# test_system = (
+# flow_func(this.perform_post_maintenance_testing)
+# .Next(this.restore_system)
+# )
+#
+# restore_system = (
+# flow_func(this.restore_system_services)
+# .Next(this.complete_maintenance)
+# )
+#
+# complete_maintenance = (
+# flow_func(this.finalize_system_maintenance)
+# .Next(this.end)
+# )
+#
+# end = flow_func(this.end_system_maintenance)
+#
+# # Flow functions
+# def start_system_maintenance(self, activation):
+# """Initialize the system maintenance process"""
+# process = activation.process
+#
+# # Send maintenance start notification
+# self.notify_maintenance_start(process.maintenance_type)
+#
+# # Create maintenance checklist
+# self.create_maintenance_checklist(process.maintenance_type)
+#
+# def notify_maintenance_window(self, activation):
+# """Send maintenance window notifications"""
+# process = activation.process
+#
+# # Send notifications to all users
+# self.send_maintenance_notifications(process.maintenance_type)
+#
+# # Mark notifications sent
+# process.notifications_sent = True
+# process.save()
+#
+# # Create system notification
+# self.create_system_notification(process.maintenance_type)
+#
+# def perform_maintenance_tasks(self, activation):
+# """Perform maintenance tasks"""
+# process = activation.process
+#
+# # Execute maintenance tasks
+# self.execute_maintenance_procedures(process.maintenance_type)
+#
+# # Mark maintenance executed
+# process.maintenance_executed = True
+# process.save()
+#
+# # Log maintenance activities
+# self.log_maintenance_activities(process.maintenance_type)
+#
+# def perform_post_maintenance_testing(self, activation):
+# """Perform post-maintenance testing"""
+# process = activation.process
+#
+# # Execute post-maintenance tests
+# test_results = self.execute_post_maintenance_tests()
+#
+# # Mark testing completed
+# process.testing_completed = True
+# process.save()
+#
+# # Store test results
+# self.store_maintenance_test_results(test_results)
+#
+# def restore_system_services(self, activation):
+# """Restore system services"""
+# process = activation.process
+#
+# # Restore all system services
+# self.restore_services()
+#
+# # Mark system restored
+# process.system_restored = True
+# process.save()
+#
+# # Verify service restoration
+# self.verify_service_restoration()
+#
+# def finalize_system_maintenance(self, activation):
+# """Finalize the system maintenance process"""
+# process = activation.process
+#
+# # Mark maintenance completed
+# process.maintenance_completed = True
+# process.save()
+#
+# # Send completion notifications
+# self.notify_maintenance_completion(process.maintenance_type)
+#
+# # Generate maintenance report
+# self.generate_maintenance_report(process.maintenance_type)
+#
+# def end_system_maintenance(self, activation):
+# """End the system maintenance workflow"""
+# process = activation.process
+#
+# # Archive maintenance records
+# self.archive_maintenance_records(process.maintenance_type)
+#
+# # Helper methods
+# def notify_maintenance_start(self, maintenance_type):
+# """Notify maintenance start"""
+# admin_team = User.objects.filter(groups__name='System Administrators')
+# for admin in admin_team:
+# send_mail(
+# subject=f'System Maintenance Started: {maintenance_type}',
+# message=f'System maintenance process started for {maintenance_type}.',
+# from_email='admin@hospital.com',
+# recipient_list=[admin.email],
+# fail_silently=True
+# )
+#
+# def create_maintenance_checklist(self, maintenance_type):
+# """Create maintenance checklist"""
+# # This would create maintenance checklist
+# pass
+#
+# def send_maintenance_notifications(self, maintenance_type):
+# """Send maintenance notifications to all users"""
+# # This would send notifications to all users
+# pass
+#
+# def create_system_notification(self, maintenance_type):
+# """Create system-wide notification"""
+# SystemNotification.objects.create(
+# title='Scheduled System Maintenance',
+# message=f'System maintenance is scheduled for {maintenance_type}.',
+# notification_type='MAINTENANCE',
+# priority='HIGH',
+# target_audience='ALL_USERS',
+# is_active=True
+# )
+#
+# def execute_maintenance_procedures(self, maintenance_type):
+# """Execute maintenance procedures"""
+# # This would execute maintenance procedures
+# pass
+#
+# def log_maintenance_activities(self, maintenance_type):
+# """Log maintenance activities"""
+# # This would log all maintenance activities
+# pass
+#
+# def execute_post_maintenance_tests(self):
+# """Execute post-maintenance tests"""
+# # This would run post-maintenance tests
+# return {'status': 'passed', 'issues': []}
+#
+# def store_maintenance_test_results(self, results):
+# """Store maintenance test results"""
+# # This would store test results
+# pass
+#
+# def restore_services(self):
+# """Restore all system services"""
+# # This would restore system services
+# pass
+#
+# def verify_service_restoration(self):
+# """Verify service restoration"""
+# # This would verify all services are restored
+# pass
+#
+# def notify_maintenance_completion(self, maintenance_type):
+# """Notify maintenance completion"""
+# all_users = User.objects.filter(is_active=True)
+# for user in all_users:
+# if user.email:
+# send_mail(
+# subject='System Maintenance Complete',
+# message=f'System maintenance for {maintenance_type} has been completed.',
+# from_email='admin@hospital.com',
+# recipient_list=[user.email],
+# fail_silently=True
+# )
+#
+# def generate_maintenance_report(self, maintenance_type):
+# """Generate maintenance report"""
+# # This would generate comprehensive maintenance report
+# pass
+#
+# def archive_maintenance_records(self, maintenance_type):
+# """Archive maintenance records"""
+# # This would archive maintenance records
+# pass
+#
+#
+# class AuditManagementProcess(Process):
+# """
+# Viewflow process model for audit management
+# """
+# audit_type = models.CharField(max_length=50, help_text='Type of audit')
+#
+# # Process status tracking
+# audit_initiated = models.BooleanField(default=False)
+# scope_defined = models.BooleanField(default=False)
+# data_collected = models.BooleanField(default=False)
+# analysis_completed = models.BooleanField(default=False)
+# findings_documented = models.BooleanField(default=False)
+# report_generated = models.BooleanField(default=False)
+# audit_completed = models.BooleanField(default=False)
+#
+# class Meta:
+# verbose_name = 'Audit Management Process'
+# verbose_name_plural = 'Audit Management Processes'
+#
+#
+# class AuditManagementFlow(Flow):
+# """
+# Audit Management Workflow
+#
+# This flow manages system audits including security,
+# compliance, and operational audits.
+# """
+#
+# process_class = AuditManagementProcess
+#
+# # Flow definition
+# start = (
+# flow_func(this.start_audit_management)
+# .Next(this.initiate_audit)
+# )
+#
+# initiate_audit = (
+# flow_func(this.setup_audit_scope)
+# .Next(this.define_scope)
+# )
+#
+# define_scope = (
+# flow_func(this.define_audit_scope)
+# .Next(this.collect_data)
+# )
+#
+# collect_data = (
+# flow_func(this.gather_audit_data)
+# .Next(this.analyze_data)
+# )
+#
+# analyze_data = (
+# flow_view(AuditReviewView)
+# .Permission('core.can_review_audits')
+# .Next(this.document_findings)
+# )
+#
+# document_findings = (
+# flow_func(this.document_audit_findings)
+# .Next(this.generate_report)
+# )
+#
+# generate_report = (
+# flow_func(this.create_audit_report)
+# .Next(this.complete_audit)
+# )
+#
+# complete_audit = (
+# flow_func(this.finalize_audit_management)
+# .Next(this.end)
+# )
+#
+# end = flow_func(this.end_audit_management)
+#
+# # Flow functions
+# def start_audit_management(self, activation):
+# """Initialize the audit management process"""
+# process = activation.process
+#
+# # Send audit start notification
+# self.notify_audit_start(process.audit_type)
+#
+# # Create audit checklist
+# self.create_audit_checklist(process.audit_type)
+#
+# def setup_audit_scope(self, activation):
+# """Setup audit scope"""
+# process = activation.process
+#
+# # Mark audit initiated
+# process.audit_initiated = True
+# process.save()
+#
+# # Configure audit parameters
+# self.configure_audit_parameters(process.audit_type)
+#
+# def define_audit_scope(self, activation):
+# """Define audit scope and criteria"""
+# process = activation.process
+#
+# # Define audit scope
+# self.establish_audit_scope(process.audit_type)
+#
+# # Mark scope defined
+# process.scope_defined = True
+# process.save()
+#
+# def gather_audit_data(self, activation):
+# """Gather audit data"""
+# process = activation.process
+#
+# # Collect audit data
+# audit_data = self.collect_audit_data(process.audit_type)
+#
+# # Mark data collected
+# process.data_collected = True
+# process.save()
+#
+# # Store audit data
+# self.store_audit_data(process.audit_type, audit_data)
+#
+# def document_audit_findings(self, activation):
+# """Document audit findings"""
+# process = activation.process
+#
+# # Document findings
+# findings = self.create_audit_findings(process.audit_type)
+#
+# # Mark findings documented
+# process.findings_documented = True
+# process.save()
+#
+# # Store findings
+# self.store_audit_findings(process.audit_type, findings)
+#
+# def create_audit_report(self, activation):
+# """Create audit report"""
+# process = activation.process
+#
+# # Generate audit report
+# report = self.generate_audit_report(process.audit_type)
+#
+# # Mark report generated
+# process.report_generated = True
+# process.save()
+#
+# # Store report
+# self.store_audit_report(process.audit_type, report)
+#
+# def finalize_audit_management(self, activation):
+# """Finalize the audit management process"""
+# process = activation.process
+#
+# # Mark audit completed
+# process.audit_completed = True
+# process.save()
+#
+# # Send completion notifications
+# self.notify_audit_completion(process.audit_type)
+#
+# # Schedule follow-up actions
+# self.schedule_audit_followup(process.audit_type)
+#
+# def end_audit_management(self, activation):
+# """End the audit management workflow"""
+# process = activation.process
+#
+# # Archive audit records
+# self.archive_audit_records(process.audit_type)
+#
+# # Helper methods
+# def notify_audit_start(self, audit_type):
+# """Notify audit start"""
+# audit_team = User.objects.filter(groups__name='Audit Team')
+# for auditor in audit_team:
+# send_mail(
+# subject=f'Audit Started: {audit_type}',
+# message=f'Audit process started for {audit_type}.',
+# from_email='audit@hospital.com',
+# recipient_list=[auditor.email],
+# fail_silently=True
+# )
+#
+# def create_audit_checklist(self, audit_type):
+# """Create audit checklist"""
+# # This would create audit checklist
+# pass
+#
+# def configure_audit_parameters(self, audit_type):
+# """Configure audit parameters"""
+# # This would configure audit parameters
+# pass
+#
+# def establish_audit_scope(self, audit_type):
+# """Establish audit scope"""
+# # This would define audit scope
+# pass
+#
+# def collect_audit_data(self, audit_type):
+# """Collect audit data"""
+# # This would collect audit data
+# return {'status': 'collected', 'records': 1000}
+#
+# def store_audit_data(self, audit_type, data):
+# """Store audit data"""
+# # This would store audit data
+# pass
+#
+# def create_audit_findings(self, audit_type):
+# """Create audit findings"""
+# # This would create audit findings
+# return {'findings': [], 'recommendations': []}
+#
+# def store_audit_findings(self, audit_type, findings):
+# """Store audit findings"""
+# # This would store findings
+# pass
+#
+# def generate_audit_report(self, audit_type):
+# """Generate audit report"""
+# # This would generate comprehensive audit report
+# return {'report_path': '/audits/report.pdf'}
+#
+# def store_audit_report(self, audit_type, report):
+# """Store audit report"""
+# # This would store audit report
+# pass
+#
+# def notify_audit_completion(self, audit_type):
+# """Notify audit completion"""
+# # This would notify relevant parties
+# pass
+#
+# def schedule_audit_followup(self, audit_type):
+# """Schedule audit follow-up"""
+# # Schedule follow-up task
+# audit_followup.apply_async(
+# args=[audit_type],
+# countdown=86400 * 30 # 30 days
+# )
+#
+# def archive_audit_records(self, audit_type):
+# """Archive audit records"""
+# # This would archive audit records
+# pass
+#
+#
+# # Celery tasks for background processing
+# @celery.job
+# def tenant_followup(tenant_id):
+# """Background task for tenant follow-up"""
+# try:
+# tenant = Tenant.objects.get(tenant_id=tenant_id)
+#
+# # Perform follow-up activities
+# # This would perform post-onboarding follow-up
+#
+# return True
+# except Exception:
+# return False
+#
+#
+# @celery.job
+# def system_health_check():
+# """Background task for system health monitoring"""
+# try:
+# # This would perform system health checks
+# return True
+# except Exception:
+# return False
+#
+#
+# @celery.job
+# def audit_followup(audit_type):
+# """Background task for audit follow-up"""
+# try:
+# # This would perform audit follow-up activities
+# return True
+# except Exception:
+# return False
+#
+#
+# @celery.job
+# def cleanup_audit_logs():
+# """Background task to cleanup old audit logs"""
+# try:
+# # This would cleanup old audit logs
+# return True
+# except Exception:
+# return False
+#
+#
+# @celery.job
+# def generate_system_reports():
+# """Background task to generate system reports"""
+# try:
+# # This would generate periodic system reports
+# return True
+# except Exception:
+# return False
+#
diff --git a/core/models.py b/core/models.py
index a0074036..459657b1 100644
--- a/core/models.py
+++ b/core/models.py
@@ -90,7 +90,7 @@ class Tenant(models.Model):
)
country = models.CharField(
max_length=100,
- default='United States',
+ default='Saudi Arabia',
help_text='Country'
)
@@ -150,7 +150,7 @@ class Tenant(models.Model):
)
currency = models.CharField(
max_length=3,
- default='USD',
+ default='SAR',
help_text='Organization currency code'
)
@@ -854,7 +854,6 @@ class IntegrationLog(models.Model):
-
class Department(models.Model):
"""
Hospital department model for organizational structure.
@@ -890,10 +889,10 @@ class Department(models.Model):
tenant = models.ForeignKey(
Tenant,
on_delete=models.CASCADE,
- related_name='departments',
+ related_name='core_departments',
help_text='Organization tenant'
)
-
+
# Department Information
department_id = models.UUIDField(
default=uuid.uuid4,
@@ -914,14 +913,14 @@ class Department(models.Model):
null=True,
help_text='Department description'
)
-
+
# Department Classification
department_type = models.CharField(
max_length=30,
choices=DEPARTMENT_TYPE_CHOICES,
help_text='Type of department'
)
-
+
# Organizational Structure
parent_department = models.ForeignKey(
'self',
@@ -931,7 +930,7 @@ class Department(models.Model):
related_name='sub_departments',
help_text='Parent department (for hierarchical structure)'
)
-
+
# Management
department_head = models.ForeignKey(
settings.AUTH_USER_MODEL,
@@ -941,7 +940,7 @@ class Department(models.Model):
related_name='headed_departments',
help_text='Department head/manager'
)
-
+
# Contact Information
phone = models.CharField(
max_length=20,
@@ -960,7 +959,7 @@ class Department(models.Model):
null=True,
help_text='Department email'
)
-
+
# Location
building = models.CharField(
max_length=50,
@@ -986,7 +985,7 @@ class Department(models.Model):
null=True,
help_text='Room numbers (e.g., 101-110, 201A-205C)'
)
-
+
# Operational Information
is_active = models.BooleanField(
default=True,
@@ -1001,7 +1000,7 @@ class Department(models.Model):
blank=True,
help_text='Operating hours by day of week'
)
-
+
# Budget and Cost Center
cost_center_code = models.CharField(
max_length=20,
@@ -1015,7 +1014,7 @@ class Department(models.Model):
null=True,
help_text='Budget code'
)
-
+
# Staffing
authorized_positions = models.PositiveIntegerField(
default=0,
@@ -1025,7 +1024,7 @@ class Department(models.Model):
default=0,
help_text='Current number of staff members'
)
-
+
# Quality and Compliance
accreditation_required = models.BooleanField(
default=False,
@@ -1047,7 +1046,7 @@ class Department(models.Model):
null=True,
help_text='Next scheduled inspection date'
)
-
+
# Metadata
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
@@ -1059,7 +1058,7 @@ class Department(models.Model):
related_name='created_departments',
help_text='User who created the department'
)
-
+
class Meta:
db_table = 'core_department'
verbose_name = 'Department'
@@ -1072,24 +1071,24 @@ class Department(models.Model):
models.Index(fields=['parent_department']),
]
unique_together = ['tenant', 'code']
-
+
def __str__(self):
return f"{self.name} ({self.code})"
-
+
@property
def full_name(self):
"""Return full department name with parent if applicable"""
if self.parent_department:
return f"{self.parent_department.name} - {self.name}"
return self.name
-
+
@property
def staffing_percentage(self):
"""Calculate current staffing percentage"""
if self.authorized_positions > 0:
return (self.current_staff_count / self.authorized_positions) * 100
return 0
-
+
def get_all_sub_departments(self):
"""Get all sub-departments recursively"""
sub_departments = []
diff --git a/db.sqlite3 b/db.sqlite3
index e52372a3..80274949 100644
Binary files a/db.sqlite3 and b/db.sqlite3 differ
diff --git a/emr/__pycache__/flows.cpython-312.pyc b/emr/__pycache__/flows.cpython-312.pyc
new file mode 100644
index 00000000..a9dc1af6
Binary files /dev/null and b/emr/__pycache__/flows.cpython-312.pyc differ
diff --git a/emr/__pycache__/urls.cpython-312.pyc b/emr/__pycache__/urls.cpython-312.pyc
index fe32c7af..cf7bccd7 100644
Binary files a/emr/__pycache__/urls.cpython-312.pyc and b/emr/__pycache__/urls.cpython-312.pyc differ
diff --git a/emr/flows.py b/emr/flows.py
new file mode 100644
index 00000000..cef76b53
--- /dev/null
+++ b/emr/flows.py
@@ -0,0 +1,929 @@
+# """
+# Viewflow workflows for EMR app.
+# Provides electronic medical record workflows for clinical documentation, care planning, and patient management.
+# """
+#
+# from viewflow import Flow, lock
+# from viewflow.base import this, flow_func
+# from viewflow.contrib import celery
+# from viewflow.decorators import flow_view
+# from viewflow.fields import CharField, ModelField
+# from viewflow.forms import ModelForm
+# from viewflow.views import CreateProcessView, UpdateProcessView
+# from viewflow.models import Process, Task
+# from django.contrib.auth.models import User
+# from django.urls import reverse_lazy
+# from django.utils import timezone
+# from django.db import transaction
+# from django.core.mail import send_mail
+#
+# from .models import Encounter, ClinicalNote, ProblemList, CarePlan, NoteTemplate
+# from .views import (
+# EncounterInitiationView, PatientAssessmentView, ClinicalDocumentationView,
+# ProblemIdentificationView, CarePlanDevelopmentView, TreatmentPlanningView,
+# ProgressMonitoringView, DischargePreparationView, QualityReviewView,
+# NoteCreationView, NoteReviewView, NoteSigningView
+# )
+#
+#
+# class ClinicalEncounterProcess(Process):
+# """
+# Viewflow process model for clinical encounters
+# """
+# encounter = ModelField(Encounter, help_text='Associated clinical encounter')
+#
+# # Process status tracking
+# encounter_initiated = models.BooleanField(default=False)
+# patient_assessed = models.BooleanField(default=False)
+# problems_identified = models.BooleanField(default=False)
+# care_plan_developed = models.BooleanField(default=False)
+# treatment_planned = models.BooleanField(default=False)
+# documentation_completed = models.BooleanField(default=False)
+# quality_reviewed = models.BooleanField(default=False)
+# encounter_finalized = models.BooleanField(default=False)
+#
+# class Meta:
+# verbose_name = 'Clinical Encounter Process'
+# verbose_name_plural = 'Clinical Encounter Processes'
+#
+#
+# class ClinicalEncounterFlow(Flow):
+# """
+# Clinical Encounter Workflow
+#
+# This flow manages the complete clinical encounter process from
+# patient assessment through documentation and quality review.
+# """
+#
+# process_class = ClinicalEncounterProcess
+#
+# # Flow definition
+# start = (
+# flow_func(this.start_encounter)
+# .Next(this.initiate_encounter)
+# )
+#
+# initiate_encounter = (
+# flow_view(EncounterInitiationView)
+# .Permission('emr.can_initiate_encounters')
+# .Next(this.assess_patient)
+# )
+#
+# assess_patient = (
+# flow_view(PatientAssessmentView)
+# .Permission('emr.can_assess_patients')
+# .Next(this.parallel_clinical_work)
+# )
+#
+# parallel_clinical_work = (
+# flow_func(this.start_parallel_clinical_work)
+# .Next(this.identify_problems)
+# .Next(this.develop_care_plan)
+# .Next(this.plan_treatment)
+# )
+#
+# identify_problems = (
+# flow_view(ProblemIdentificationView)
+# .Permission('emr.can_identify_problems')
+# .Next(this.join_clinical_work)
+# )
+#
+# develop_care_plan = (
+# flow_view(CarePlanDevelopmentView)
+# .Permission('emr.can_develop_care_plans')
+# .Next(this.join_clinical_work)
+# )
+#
+# plan_treatment = (
+# flow_view(TreatmentPlanningView)
+# .Permission('emr.can_plan_treatment')
+# .Next(this.join_clinical_work)
+# )
+#
+# join_clinical_work = (
+# flow_func(this.join_parallel_clinical_work)
+# .Next(this.complete_documentation)
+# )
+#
+# complete_documentation = (
+# flow_view(ClinicalDocumentationView)
+# .Permission('emr.can_complete_documentation')
+# .Next(this.review_quality)
+# )
+#
+# review_quality = (
+# flow_view(QualityReviewView)
+# .Permission('emr.can_review_quality')
+# .Next(this.finalize_encounter)
+# )
+#
+# finalize_encounter = (
+# flow_func(this.complete_encounter)
+# .Next(this.end)
+# )
+#
+# end = flow_func(this.end_encounter)
+#
+# # Flow functions
+# def start_encounter(self, activation):
+# """Initialize the clinical encounter process"""
+# process = activation.process
+# encounter = process.encounter
+#
+# # Update encounter status
+# encounter.status = 'IN_PROGRESS'
+# encounter.save()
+#
+# # Send notification to clinical staff
+# self.notify_clinical_staff(encounter)
+#
+# # Check for high-priority encounters
+# if encounter.encounter_type in ['EMERGENCY', 'URGENT_CARE']:
+# self.notify_priority_encounter(encounter)
+#
+# def start_parallel_clinical_work(self, activation):
+# """Start parallel clinical work tasks"""
+# process = activation.process
+#
+# # Create parallel clinical tasks
+# self.create_clinical_tasks(process.encounter)
+#
+# def join_parallel_clinical_work(self, activation):
+# """Wait for all clinical work to complete"""
+# process = activation.process
+#
+# # Check if all clinical work is completed
+# if (process.problems_identified and
+# process.care_plan_developed and
+# process.treatment_planned):
+#
+# # Proceed to documentation
+# self.notify_documentation_ready(process.encounter)
+#
+# def complete_encounter(self, activation):
+# """Finalize the clinical encounter process"""
+# process = activation.process
+# encounter = process.encounter
+#
+# # Update encounter status
+# encounter.status = 'COMPLETED'
+# encounter.end_datetime = timezone.now()
+# encounter.save()
+#
+# # Mark process as completed
+# process.encounter_finalized = True
+# process.save()
+#
+# # Send completion notifications
+# self.notify_encounter_completion(encounter)
+#
+# # Update clinical metrics
+# self.update_clinical_metrics(encounter)
+#
+# # Schedule follow-up if needed
+# self.schedule_follow_up(encounter)
+#
+# def end_encounter(self, activation):
+# """End the clinical encounter workflow"""
+# process = activation.process
+#
+# # Generate encounter summary report
+# self.generate_encounter_summary(process.encounter)
+#
+# # Helper methods
+# def notify_clinical_staff(self, encounter):
+# """Notify clinical staff of new encounter"""
+# from django.contrib.auth.models import Group
+#
+# clinical_staff = User.objects.filter(
+# groups__name='Clinical Staff'
+# )
+#
+# for staff in clinical_staff:
+# send_mail(
+# subject=f'New Clinical Encounter: {encounter.patient.get_full_name()}',
+# message=f'New {encounter.get_encounter_type_display()} encounter started.',
+# from_email='clinical@hospital.com',
+# recipient_list=[staff.email],
+# fail_silently=True
+# )
+#
+# def notify_priority_encounter(self, encounter):
+# """Notify of priority encounter"""
+# supervisors = User.objects.filter(
+# groups__name='Clinical Supervisors'
+# )
+#
+# for supervisor in supervisors:
+# send_mail(
+# subject=f'PRIORITY Encounter: {encounter.patient.get_full_name()}',
+# message=f'{encounter.get_encounter_type_display()} encounter requires immediate attention.',
+# from_email='clinical@hospital.com',
+# recipient_list=[supervisor.email],
+# fail_silently=True
+# )
+#
+# def create_clinical_tasks(self, encounter):
+# """Create clinical work tasks"""
+# # This would create tasks in a task management system
+# pass
+#
+# def notify_documentation_ready(self, encounter):
+# """Notify that documentation is ready"""
+# if encounter.provider and encounter.provider.email:
+# send_mail(
+# subject=f'Documentation Ready: {encounter.patient.get_full_name()}',
+# message=f'Clinical work completed, ready for documentation.',
+# from_email='clinical@hospital.com',
+# recipient_list=[encounter.provider.email],
+# fail_silently=True
+# )
+#
+# def notify_encounter_completion(self, encounter):
+# """Notify encounter completion"""
+# # Notify care team
+# care_team = encounter.care_team.all()
+# for member in care_team:
+# if member.email:
+# send_mail(
+# subject=f'Encounter Completed: {encounter.patient.get_full_name()}',
+# message=f'Clinical encounter has been completed and documented.',
+# from_email='clinical@hospital.com',
+# recipient_list=[member.email],
+# fail_silently=True
+# )
+#
+# def update_clinical_metrics(self, encounter):
+# """Update clinical quality metrics"""
+# # This would update clinical performance metrics
+# pass
+#
+# def schedule_follow_up(self, encounter):
+# """Schedule follow-up appointments if needed"""
+# # This would schedule follow-up appointments
+# pass
+#
+# def generate_encounter_summary(self, encounter):
+# """Generate encounter summary report"""
+# # This would generate a comprehensive encounter report
+# pass
+#
+#
+# class ClinicalDocumentationProcess(Process):
+# """
+# Viewflow process model for clinical documentation
+# """
+# clinical_note = ModelField(ClinicalNote, help_text='Associated clinical note')
+#
+# # Process status tracking
+# note_initiated = models.BooleanField(default=False)
+# content_drafted = models.BooleanField(default=False)
+# clinical_review_completed = models.BooleanField(default=False)
+# quality_check_completed = models.BooleanField(default=False)
+# note_signed = models.BooleanField(default=False)
+# note_finalized = models.BooleanField(default=False)
+#
+# class Meta:
+# verbose_name = 'Clinical Documentation Process'
+# verbose_name_plural = 'Clinical Documentation Processes'
+#
+#
+# class ClinicalDocumentationFlow(Flow):
+# """
+# Clinical Documentation Workflow
+#
+# This flow manages clinical note creation, review, and finalization
+# with quality checks and electronic signatures.
+# """
+#
+# process_class = ClinicalDocumentationProcess
+#
+# # Flow definition
+# start = (
+# flow_func(this.start_documentation)
+# .Next(this.create_note)
+# )
+#
+# create_note = (
+# flow_view(NoteCreationView)
+# .Permission('emr.can_create_notes')
+# .Next(this.draft_content)
+# )
+#
+# draft_content = (
+# flow_view(NoteDraftingView)
+# .Permission('emr.can_draft_notes')
+# .Next(this.review_note)
+# )
+#
+# review_note = (
+# flow_view(NoteReviewView)
+# .Permission('emr.can_review_notes')
+# .Next(this.quality_check)
+# )
+#
+# quality_check = (
+# flow_view(NoteQualityCheckView)
+# .Permission('emr.can_quality_check_notes')
+# .Next(this.sign_note)
+# )
+#
+# sign_note = (
+# flow_view(NoteSigningView)
+# .Permission('emr.can_sign_notes')
+# .Next(this.finalize_note)
+# )
+#
+# finalize_note = (
+# flow_func(this.complete_documentation)
+# .Next(this.end)
+# )
+#
+# end = flow_func(this.end_documentation)
+#
+# # Flow functions
+# def start_documentation(self, activation):
+# """Initialize the documentation process"""
+# process = activation.process
+# note = process.clinical_note
+#
+# # Update note status
+# note.status = 'DRAFT'
+# note.save()
+#
+# # Send notification to documenting provider
+# self.notify_documentation_required(note)
+#
+# def complete_documentation(self, activation):
+# """Finalize the documentation process"""
+# process = activation.process
+# note = process.clinical_note
+#
+# # Update note status
+# note.status = 'FINAL'
+# note.finalized_datetime = timezone.now()
+# note.save()
+#
+# # Mark process as completed
+# process.note_finalized = True
+# process.save()
+#
+# # Send completion notifications
+# self.notify_documentation_completion(note)
+#
+# # Update documentation metrics
+# self.update_documentation_metrics(note)
+#
+# def end_documentation(self, activation):
+# """End the documentation workflow"""
+# process = activation.process
+#
+# # Generate documentation summary
+# self.generate_documentation_summary(process.clinical_note)
+#
+# # Helper methods
+# def notify_documentation_required(self, note):
+# """Notify provider that documentation is required"""
+# if note.author and note.author.email:
+# send_mail(
+# subject=f'Documentation Required: {note.patient.get_full_name()}',
+# message=f'{note.get_note_type_display()} requires completion.',
+# from_email='documentation@hospital.com',
+# recipient_list=[note.author.email],
+# fail_silently=True
+# )
+#
+# def notify_documentation_completion(self, note):
+# """Notify documentation completion"""
+# # Notify care team
+# if note.encounter:
+# care_team = note.encounter.care_team.all()
+# for member in care_team:
+# if member.email:
+# send_mail(
+# subject=f'Documentation Complete: {note.patient.get_full_name()}',
+# message=f'{note.get_note_type_display()} has been completed and signed.',
+# from_email='documentation@hospital.com',
+# recipient_list=[member.email],
+# fail_silently=True
+# )
+#
+# def update_documentation_metrics(self, note):
+# """Update documentation quality metrics"""
+# # This would update documentation performance metrics
+# pass
+#
+# def generate_documentation_summary(self, note):
+# """Generate documentation summary"""
+# # This would generate documentation summary
+# pass
+#
+#
+# class CarePlanManagementProcess(Process):
+# """
+# Viewflow process model for care plan management
+# """
+# care_plan = ModelField(CarePlan, help_text='Associated care plan')
+#
+# # Process status tracking
+# plan_initiated = models.BooleanField(default=False)
+# assessment_completed = models.BooleanField(default=False)
+# goals_established = models.BooleanField(default=False)
+# interventions_planned = models.BooleanField(default=False)
+# team_assigned = models.BooleanField(default=False)
+# plan_approved = models.BooleanField(default=False)
+# implementation_started = models.BooleanField(default=False)
+# progress_monitored = models.BooleanField(default=False)
+# plan_completed = models.BooleanField(default=False)
+#
+# class Meta:
+# verbose_name = 'Care Plan Management Process'
+# verbose_name_plural = 'Care Plan Management Processes'
+#
+#
+# class CarePlanManagementFlow(Flow):
+# """
+# Care Plan Management Workflow
+#
+# This flow manages care plan development, approval, implementation,
+# and monitoring with multidisciplinary team coordination.
+# """
+#
+# process_class = CarePlanManagementProcess
+#
+# # Flow definition
+# start = (
+# flow_func(this.start_care_planning)
+# .Next(this.initiate_plan)
+# )
+#
+# initiate_plan = (
+# flow_view(CarePlanInitiationView)
+# .Permission('emr.can_initiate_care_plans')
+# .Next(this.complete_assessment)
+# )
+#
+# complete_assessment = (
+# flow_view(CarePlanAssessmentView)
+# .Permission('emr.can_assess_care_plans')
+# .Next(this.establish_goals)
+# )
+#
+# establish_goals = (
+# flow_view(GoalEstablishmentView)
+# .Permission('emr.can_establish_goals')
+# .Next(this.plan_interventions)
+# )
+#
+# plan_interventions = (
+# flow_view(InterventionPlanningView)
+# .Permission('emr.can_plan_interventions')
+# .Next(this.assign_care_team)
+# )
+#
+# assign_care_team = (
+# flow_view(CareTeamAssignmentView)
+# .Permission('emr.can_assign_care_team')
+# .Next(this.approve_plan)
+# )
+#
+# approve_plan = (
+# flow_view(CarePlanApprovalView)
+# .Permission('emr.can_approve_care_plans')
+# .Next(this.implement_plan)
+# )
+#
+# implement_plan = (
+# flow_func(this.start_implementation)
+# .Next(this.monitor_progress)
+# )
+#
+# monitor_progress = (
+# flow_view(ProgressMonitoringView)
+# .Permission('emr.can_monitor_progress')
+# .Next(this.complete_plan)
+# )
+#
+# complete_plan = (
+# flow_func(this.finalize_care_plan)
+# .Next(this.end)
+# )
+#
+# end = flow_func(this.end_care_planning)
+#
+# # Flow functions
+# def start_care_planning(self, activation):
+# """Initialize the care planning process"""
+# process = activation.process
+# plan = process.care_plan
+#
+# # Update plan status
+# plan.status = 'DRAFT'
+# plan.save()
+#
+# # Send notification to care team
+# self.notify_care_planning_start(plan)
+#
+# def start_implementation(self, activation):
+# """Start care plan implementation"""
+# process = activation.process
+# plan = process.care_plan
+#
+# # Update plan status
+# plan.status = 'ACTIVE'
+# plan.save()
+#
+# # Mark implementation started
+# process.implementation_started = True
+# process.save()
+#
+# # Notify care team of implementation
+# self.notify_implementation_start(plan)
+#
+# # Schedule monitoring activities
+# self.schedule_monitoring(plan)
+#
+# def finalize_care_plan(self, activation):
+# """Finalize the care plan process"""
+# process = activation.process
+# plan = process.care_plan
+#
+# # Update plan status based on completion
+# if plan.completion_percentage >= 100:
+# plan.status = 'COMPLETED'
+# else:
+# plan.status = 'ON_HOLD'
+#
+# plan.save()
+#
+# # Mark process as completed
+# process.plan_completed = True
+# process.save()
+#
+# # Send completion notifications
+# self.notify_care_plan_completion(plan)
+#
+# # Generate outcomes report
+# self.generate_outcomes_report(plan)
+#
+# def end_care_planning(self, activation):
+# """End the care planning workflow"""
+# process = activation.process
+#
+# # Generate care plan summary
+# self.generate_care_plan_summary(process.care_plan)
+#
+# # Helper methods
+# def notify_care_planning_start(self, plan):
+# """Notify care team of care planning start"""
+# care_team = plan.care_team.all()
+# for member in care_team:
+# if member.email:
+# send_mail(
+# subject=f'Care Plan Development: {plan.patient.get_full_name()}',
+# message=f'Care plan development has started for {plan.title}.',
+# from_email='careplanning@hospital.com',
+# recipient_list=[member.email],
+# fail_silently=True
+# )
+#
+# def notify_implementation_start(self, plan):
+# """Notify care team of implementation start"""
+# care_team = plan.care_team.all()
+# for member in care_team:
+# if member.email:
+# send_mail(
+# subject=f'Care Plan Implementation: {plan.patient.get_full_name()}',
+# message=f'Care plan implementation has started for {plan.title}.',
+# from_email='careplanning@hospital.com',
+# recipient_list=[member.email],
+# fail_silently=True
+# )
+#
+# def schedule_monitoring(self, plan):
+# """Schedule monitoring activities"""
+# # This would schedule monitoring tasks
+# pass
+#
+# def notify_care_plan_completion(self, plan):
+# """Notify care plan completion"""
+# # Notify patient if email available
+# if plan.patient.email:
+# send_mail(
+# subject='Care Plan Completed',
+# message=f'Your care plan "{plan.title}" has been completed.',
+# from_email='careplanning@hospital.com',
+# recipient_list=[plan.patient.email],
+# fail_silently=True
+# )
+#
+# def generate_outcomes_report(self, plan):
+# """Generate care plan outcomes report"""
+# # This would generate outcomes report
+# pass
+#
+# def generate_care_plan_summary(self, plan):
+# """Generate care plan summary"""
+# # This would generate care plan summary
+# pass
+#
+#
+# class ProblemManagementProcess(Process):
+# """
+# Viewflow process model for problem management
+# """
+# problem = ModelField(ProblemList, help_text='Associated problem')
+#
+# # Process status tracking
+# problem_identified = models.BooleanField(default=False)
+# problem_assessed = models.BooleanField(default=False)
+# treatment_planned = models.BooleanField(default=False)
+# interventions_implemented = models.BooleanField(default=False)
+# progress_monitored = models.BooleanField(default=False)
+# problem_resolved = models.BooleanField(default=False)
+#
+# class Meta:
+# verbose_name = 'Problem Management Process'
+# verbose_name_plural = 'Problem Management Processes'
+#
+#
+# class ProblemManagementFlow(Flow):
+# """
+# Problem Management Workflow
+#
+# This flow manages clinical problem identification, assessment,
+# treatment planning, and resolution tracking.
+# """
+#
+# process_class = ProblemManagementProcess
+#
+# # Flow definition
+# start = (
+# flow_func(this.start_problem_management)
+# .Next(this.identify_problem)
+# )
+#
+# identify_problem = (
+# flow_view(ProblemIdentificationView)
+# .Permission('emr.can_identify_problems')
+# .Next(this.assess_problem)
+# )
+#
+# assess_problem = (
+# flow_view(ProblemAssessmentView)
+# .Permission('emr.can_assess_problems')
+# .Next(this.plan_treatment)
+# )
+#
+# plan_treatment = (
+# flow_view(TreatmentPlanningView)
+# .Permission('emr.can_plan_treatment')
+# .Next(this.implement_interventions)
+# )
+#
+# implement_interventions = (
+# flow_view(InterventionImplementationView)
+# .Permission('emr.can_implement_interventions')
+# .Next(this.monitor_progress)
+# )
+#
+# monitor_progress = (
+# flow_view(ProgressMonitoringView)
+# .Permission('emr.can_monitor_progress')
+# .Next(this.resolve_problem)
+# )
+#
+# resolve_problem = (
+# flow_func(this.complete_problem_management)
+# .Next(this.end)
+# )
+#
+# end = flow_func(this.end_problem_management)
+#
+# # Flow functions
+# def start_problem_management(self, activation):
+# """Initialize the problem management process"""
+# process = activation.process
+# problem = process.problem
+#
+# # Update problem status
+# problem.status = 'ACTIVE'
+# problem.save()
+#
+# # Send notification to care team
+# self.notify_problem_identified(problem)
+#
+# def complete_problem_management(self, activation):
+# """Finalize the problem management process"""
+# process = activation.process
+# problem = process.problem
+#
+# # Update problem status
+# if problem.resolution_date:
+# problem.status = 'RESOLVED'
+# else:
+# problem.status = 'ONGOING'
+#
+# problem.save()
+#
+# # Mark process as completed
+# process.problem_resolved = True
+# process.save()
+#
+# # Send completion notifications
+# self.notify_problem_resolution(problem)
+#
+# def end_problem_management(self, activation):
+# """End the problem management workflow"""
+# process = activation.process
+#
+# # Generate problem summary
+# self.generate_problem_summary(process.problem)
+#
+# # Helper methods
+# def notify_problem_identified(self, problem):
+# """Notify care team of problem identification"""
+# # This would notify the care team
+# pass
+#
+# def notify_problem_resolution(self, problem):
+# """Notify problem resolution"""
+# # This would notify relevant parties
+# pass
+#
+# def generate_problem_summary(self, problem):
+# """Generate problem management summary"""
+# # This would generate problem summary
+# pass
+#
+#
+# class QualityAssuranceProcess(Process):
+# """
+# Viewflow process model for clinical quality assurance
+# """
+# encounter_id = CharField(max_length=50, help_text='Encounter identifier')
+# review_type = CharField(max_length=20, help_text='Type of quality review')
+#
+# # Process status tracking
+# review_initiated = models.BooleanField(default=False)
+# documentation_reviewed = models.BooleanField(default=False)
+# clinical_indicators_checked = models.BooleanField(default=False)
+# compliance_verified = models.BooleanField(default=False)
+# feedback_provided = models.BooleanField(default=False)
+# quality_review_completed = models.BooleanField(default=False)
+#
+# class Meta:
+# verbose_name = 'Quality Assurance Process'
+# verbose_name_plural = 'Quality Assurance Processes'
+#
+#
+# class QualityAssuranceFlow(Flow):
+# """
+# Clinical Quality Assurance Workflow
+#
+# This flow manages clinical quality reviews including documentation
+# quality, clinical indicators, and compliance verification.
+# """
+#
+# process_class = QualityAssuranceProcess
+#
+# # Flow definition
+# start = (
+# flow_func(this.start_quality_review)
+# .Next(this.review_documentation)
+# )
+#
+# review_documentation = (
+# flow_view(DocumentationReviewView)
+# .Permission('emr.can_review_documentation')
+# .Next(this.check_clinical_indicators)
+# )
+#
+# check_clinical_indicators = (
+# flow_view(ClinicalIndicatorCheckView)
+# .Permission('emr.can_check_clinical_indicators')
+# .Next(this.verify_compliance)
+# )
+#
+# verify_compliance = (
+# flow_view(ComplianceVerificationView)
+# .Permission('emr.can_verify_compliance')
+# .Next(this.provide_feedback)
+# )
+#
+# provide_feedback = (
+# flow_view(QualityFeedbackView)
+# .Permission('emr.can_provide_quality_feedback')
+# .Next(this.complete_review)
+# )
+#
+# complete_review = (
+# flow_func(this.finalize_quality_review)
+# .Next(this.end)
+# )
+#
+# end = flow_func(this.end_quality_review)
+#
+# # Flow functions
+# def start_quality_review(self, activation):
+# """Initialize the quality review process"""
+# process = activation.process
+#
+# # Notify quality staff
+# self.notify_quality_staff(process.encounter_id, process.review_type)
+#
+# def finalize_quality_review(self, activation):
+# """Finalize the quality review process"""
+# process = activation.process
+#
+# # Mark review as completed
+# process.quality_review_completed = True
+# process.save()
+#
+# # Generate quality report
+# self.generate_quality_report(process.encounter_id, process.review_type)
+#
+# def end_quality_review(self, activation):
+# """End the quality review workflow"""
+# process = activation.process
+#
+# # Update quality metrics
+# self.update_quality_metrics(process.encounter_id, process.review_type)
+#
+# # Helper methods
+# def notify_quality_staff(self, encounter_id, review_type):
+# """Notify quality staff"""
+# quality_staff = User.objects.filter(
+# groups__name='Quality Assurance'
+# )
+#
+# for staff in quality_staff:
+# send_mail(
+# subject=f'Quality Review Required: {encounter_id}',
+# message=f'{review_type} quality review required for encounter {encounter_id}.',
+# from_email='quality@hospital.com',
+# recipient_list=[staff.email],
+# fail_silently=True
+# )
+#
+# def generate_quality_report(self, encounter_id, review_type):
+# """Generate quality report"""
+# # This would generate quality report
+# pass
+#
+# def update_quality_metrics(self, encounter_id, review_type):
+# """Update quality metrics"""
+# # This would update quality metrics
+# pass
+#
+#
+# # Celery tasks for background processing
+# @celery.job
+# def auto_generate_care_plans():
+# """Background task to automatically generate care plans"""
+# try:
+# # This would generate care plans based on problems
+# return True
+# except Exception:
+# return False
+#
+#
+# @celery.job
+# def monitor_documentation_compliance():
+# """Background task to monitor documentation compliance"""
+# try:
+# # This would monitor documentation timeliness
+# return True
+# except Exception:
+# return False
+#
+#
+# @celery.job
+# def generate_clinical_reports():
+# """Background task to generate clinical reports"""
+# try:
+# # This would generate clinical quality reports
+# return True
+# except Exception:
+# return False
+#
+#
+# @celery.job
+# def auto_schedule_care_plan_reviews():
+# """Background task to schedule care plan reviews"""
+# try:
+# # This would schedule care plan reviews
+# return True
+# except Exception:
+# return False
+#
+#
+# @celery.job
+# def identify_quality_indicators():
+# """Background task to identify quality indicators"""
+# try:
+# # This would identify quality improvement opportunities
+# return True
+# except Exception:
+# return False
+#
diff --git a/emr/urls.py b/emr/urls.py
index 71c27d78..3ca745f7 100644
--- a/emr/urls.py
+++ b/emr/urls.py
@@ -11,7 +11,7 @@ urlpatterns = [
# Main views
path('', views.EMRDashboardView.as_view(), name='dashboard'),
path('encounters/', views.EncounterListView.as_view(), name='encounter_list'),
- path('encounters//', views.EncounterDetailView.as_view(), name='encounter_detail'),
+ path('encounters//', views.EncounterDetailView.as_view(), name='encounter_detail'),
# path('encounters//update/', views.EncounterUpdateView.as_view(), name='encounter_update'),
# path('encounters//delete/', views.EncounterDeleteView.as_view(), name='encounter_delete'),
path('encounters/create/', views.EncounterCreateView.as_view(), name='encounter_create'),
diff --git a/hospital_management/__pycache__/settings.cpython-312.pyc b/hospital_management/__pycache__/settings.cpython-312.pyc
index dbcf00eb..fad854ec 100644
Binary files a/hospital_management/__pycache__/settings.cpython-312.pyc and b/hospital_management/__pycache__/settings.cpython-312.pyc differ
diff --git a/hospital_management/settings.py b/hospital_management/settings.py
index d5b04d12..41bce3d5 100644
--- a/hospital_management/settings.py
+++ b/hospital_management/settings.py
@@ -46,6 +46,8 @@ THIRD_PARTY_APPS = [
'corsheaders',
'django_extensions',
'allauth',
+ 'viewflow',
+ 'viewflow.workflow',
# 'allauth.socialaccount',
]
diff --git a/hr/__pycache__/flows.cpython-312.pyc b/hr/__pycache__/flows.cpython-312.pyc
new file mode 100644
index 00000000..58e95d4f
Binary files /dev/null and b/hr/__pycache__/flows.cpython-312.pyc differ
diff --git a/hr/__pycache__/models.cpython-312.pyc b/hr/__pycache__/models.cpython-312.pyc
index ccfa36e3..21574f34 100644
Binary files a/hr/__pycache__/models.cpython-312.pyc and b/hr/__pycache__/models.cpython-312.pyc differ
diff --git a/hr/__pycache__/urls.cpython-312.pyc b/hr/__pycache__/urls.cpython-312.pyc
index 0ae99261..8ff4cc55 100644
Binary files a/hr/__pycache__/urls.cpython-312.pyc and b/hr/__pycache__/urls.cpython-312.pyc differ
diff --git a/hr/__pycache__/views.cpython-312.pyc b/hr/__pycache__/views.cpython-312.pyc
index 65d387e8..cedb4c60 100644
Binary files a/hr/__pycache__/views.cpython-312.pyc and b/hr/__pycache__/views.cpython-312.pyc differ
diff --git a/hr/flows.py b/hr/flows.py
new file mode 100644
index 00000000..4aefd4c2
--- /dev/null
+++ b/hr/flows.py
@@ -0,0 +1,846 @@
+# """
+# Viewflow workflows for HR app.
+# Provides employee onboarding, performance review, and training workflows.
+# """
+#
+# from viewflow import Flow, lock
+# from viewflow.base import this, flow_func
+# from viewflow.contrib import celery
+# from viewflow.decorators import flow_view
+# from viewflow.fields import CharField, ModelField
+# from viewflow.forms import ModelForm
+# from viewflow.views import CreateProcessView, UpdateProcessView
+# from viewflow.models import Process, Task
+# from django.contrib.auth.models import User
+# from django.urls import reverse_lazy
+# from django.utils import timezone
+# from django.db import transaction
+# from django.core.mail import send_mail
+#
+# from .models import Employee, PerformanceReview, TrainingRecord
+# from .views import (
+# EmployeeOnboardingView, DocumentCollectionView, SystemAccessSetupView,
+# OrientationSchedulingView, PerformanceReviewInitiationView,
+# SelfAssessmentView, ManagerReviewView, ReviewMeetingView,
+# TrainingNeedsAssessmentView, TrainingSchedulingView, TrainingDeliveryView,
+# TrainingEvaluationView
+# )
+#
+#
+# class EmployeeOnboardingProcess(Process):
+# """
+# Viewflow process model for employee onboarding
+# """
+# employee = ModelField(Employee, help_text='Associated employee')
+#
+# # Process status tracking
+# employee_created = models.BooleanField(default=False)
+# documents_collected = models.BooleanField(default=False)
+# system_access_setup = models.BooleanField(default=False)
+# orientation_scheduled = models.BooleanField(default=False)
+# orientation_completed = models.BooleanField(default=False)
+# probationary_review_scheduled = models.BooleanField(default=False)
+# onboarding_completed = models.BooleanField(default=False)
+#
+# class Meta:
+# verbose_name = 'Employee Onboarding Process'
+# verbose_name_plural = 'Employee Onboarding Processes'
+#
+#
+# class EmployeeOnboardingFlow(Flow):
+# """
+# Employee Onboarding Workflow
+#
+# This flow manages the complete employee onboarding process from
+# initial setup through orientation and probationary period setup.
+# """
+#
+# process_class = EmployeeOnboardingProcess
+#
+# # Flow definition
+# start = (
+# flow_func(this.start_onboarding)
+# .Next(this.create_employee_record)
+# )
+#
+# create_employee_record = (
+# flow_view(EmployeeOnboardingView)
+# .Permission('hr.can_create_employees')
+# .Next(this.collect_documents)
+# )
+#
+# collect_documents = (
+# flow_view(DocumentCollectionView)
+# .Permission('hr.can_collect_documents')
+# .Next(this.setup_system_access)
+# )
+#
+# setup_system_access = (
+# flow_view(SystemAccessSetupView)
+# .Permission('hr.can_setup_system_access')
+# .Next(this.schedule_orientation)
+# )
+#
+# schedule_orientation = (
+# flow_view(OrientationSchedulingView)
+# .Permission('hr.can_schedule_orientation')
+# .Next(this.conduct_orientation)
+# )
+#
+# conduct_orientation = (
+# flow_view(OrientationDeliveryView)
+# .Permission('hr.can_conduct_orientation')
+# .Next(this.schedule_probationary_review)
+# )
+#
+# schedule_probationary_review = (
+# flow_func(this.setup_probationary_review)
+# .Next(this.finalize_onboarding)
+# )
+#
+# finalize_onboarding = (
+# flow_func(this.complete_onboarding)
+# .Next(this.end)
+# )
+#
+# end = flow_func(this.end_onboarding)
+#
+# # Flow functions
+# def start_onboarding(self, activation):
+# """Initialize the onboarding process"""
+# process = activation.process
+# employee = process.employee
+#
+# # Send welcome notification
+# self.send_welcome_notification(employee)
+#
+# # Notify HR staff
+# self.notify_hr_staff(employee)
+#
+# def setup_probationary_review(self, activation):
+# """Setup probationary review"""
+# process = activation.process
+# employee = process.employee
+#
+# # Schedule probationary review (typically 90 days)
+# review_date = timezone.now().date() + timezone.timedelta(days=90)
+#
+# # Create probationary review record
+# PerformanceReview.objects.create(
+# employee=employee,
+# review_period_start=employee.hire_date,
+# review_period_end=review_date,
+# review_date=review_date,
+# review_type='PROBATIONARY',
+# status='DRAFT'
+# )
+#
+# process.probationary_review_scheduled = True
+# process.save()
+#
+# # Notify manager
+# self.notify_manager_probationary_review(employee, review_date)
+#
+# def complete_onboarding(self, activation):
+# """Finalize the onboarding process"""
+# process = activation.process
+# employee = process.employee
+#
+# # Update employee status
+# employee.employment_status = 'ACTIVE'
+# employee.save()
+#
+# # Mark process as completed
+# process.onboarding_completed = True
+# process.save()
+#
+# # Send completion notifications
+# self.notify_onboarding_completion(employee)
+#
+# def end_onboarding(self, activation):
+# """End the onboarding workflow"""
+# process = activation.process
+#
+# # Generate onboarding summary report
+# self.generate_onboarding_summary(process.employee)
+#
+# # Helper methods
+# def send_welcome_notification(self, employee):
+# """Send welcome notification to new employee"""
+# if employee.email:
+# send_mail(
+# subject=f'Welcome to {employee.tenant.name}!',
+# message=f'Welcome {employee.first_name}! Your onboarding process has begun.',
+# from_email='hr@hospital.com',
+# recipient_list=[employee.email],
+# fail_silently=True
+# )
+#
+# def notify_hr_staff(self, employee):
+# """Notify HR staff of new employee onboarding"""
+# from django.contrib.auth.models import Group
+#
+# hr_staff = User.objects.filter(
+# groups__name='HR Staff'
+# )
+#
+# for staff in hr_staff:
+# send_mail(
+# subject=f'New Employee Onboarding: {employee.get_full_name()}',
+# message=f'New employee {employee.get_full_name()} onboarding has started.',
+# from_email='hr@hospital.com',
+# recipient_list=[staff.email],
+# fail_silently=True
+# )
+#
+# def notify_manager_probationary_review(self, employee, review_date):
+# """Notify manager of upcoming probationary review"""
+# if employee.manager and employee.manager.email:
+# send_mail(
+# subject=f'Probationary Review Scheduled: {employee.get_full_name()}',
+# message=f'Probationary review scheduled for {review_date}.',
+# from_email='hr@hospital.com',
+# recipient_list=[employee.manager.email],
+# fail_silently=True
+# )
+#
+# def notify_onboarding_completion(self, employee):
+# """Notify relevant parties of onboarding completion"""
+# # Notify employee
+# if employee.email:
+# send_mail(
+# subject='Onboarding Complete',
+# message=f'Congratulations {employee.first_name}! Your onboarding is complete.',
+# from_email='hr@hospital.com',
+# recipient_list=[employee.email],
+# fail_silently=True
+# )
+#
+# # Notify manager
+# if employee.manager and employee.manager.email:
+# send_mail(
+# subject=f'Employee Onboarding Complete: {employee.get_full_name()}',
+# message=f'{employee.get_full_name()} has completed onboarding.',
+# from_email='hr@hospital.com',
+# recipient_list=[employee.manager.email],
+# fail_silently=True
+# )
+#
+# def generate_onboarding_summary(self, employee):
+# """Generate onboarding summary report"""
+# # This would generate a comprehensive onboarding report
+# pass
+#
+#
+# class PerformanceReviewProcess(Process):
+# """
+# Viewflow process model for performance reviews
+# """
+# performance_review = ModelField(PerformanceReview, help_text='Associated performance review')
+#
+# # Process status tracking
+# review_initiated = models.BooleanField(default=False)
+# self_assessment_completed = models.BooleanField(default=False)
+# manager_review_completed = models.BooleanField(default=False)
+# review_meeting_held = models.BooleanField(default=False)
+# employee_acknowledged = models.BooleanField(default=False)
+# development_plan_created = models.BooleanField(default=False)
+# review_finalized = models.BooleanField(default=False)
+#
+# class Meta:
+# verbose_name = 'Performance Review Process'
+# verbose_name_plural = 'Performance Review Processes'
+#
+#
+# class PerformanceReviewFlow(Flow):
+# """
+# Performance Review Workflow
+#
+# This flow manages the complete performance review process including
+# self-assessment, manager review, meeting, and development planning.
+# """
+#
+# process_class = PerformanceReviewProcess
+#
+# # Flow definition
+# start = (
+# flow_func(this.start_performance_review)
+# .Next(this.initiate_review)
+# )
+#
+# initiate_review = (
+# flow_view(PerformanceReviewInitiationView)
+# .Permission('hr.can_initiate_reviews')
+# .Next(this.employee_self_assessment)
+# )
+#
+# employee_self_assessment = (
+# flow_view(SelfAssessmentView)
+# .Permission('hr.can_complete_self_assessment')
+# .Next(this.manager_review)
+# )
+#
+# manager_review = (
+# flow_view(ManagerReviewView)
+# .Permission('hr.can_conduct_manager_review')
+# .Next(this.review_meeting)
+# )
+#
+# review_meeting = (
+# flow_view(ReviewMeetingView)
+# .Permission('hr.can_conduct_review_meeting')
+# .Next(this.employee_acknowledgment)
+# )
+#
+# employee_acknowledgment = (
+# flow_view(EmployeeAcknowledgmentView)
+# .Permission('hr.can_acknowledge_review')
+# .Next(this.create_development_plan)
+# )
+#
+# create_development_plan = (
+# flow_view(DevelopmentPlanView)
+# .Permission('hr.can_create_development_plan')
+# .Next(this.finalize_review)
+# )
+#
+# finalize_review = (
+# flow_func(this.complete_performance_review)
+# .Next(this.end)
+# )
+#
+# end = flow_func(this.end_performance_review)
+#
+# # Flow functions
+# def start_performance_review(self, activation):
+# """Initialize the performance review process"""
+# process = activation.process
+# review = process.performance_review
+#
+# # Update review status
+# review.status = 'IN_PROGRESS'
+# review.save()
+#
+# # Notify employee and manager
+# self.notify_review_start(review)
+#
+# def complete_performance_review(self, activation):
+# """Finalize the performance review process"""
+# process = activation.process
+# review = process.performance_review
+#
+# # Update review status
+# review.status = 'COMPLETED'
+# review.save()
+#
+# # Mark process as completed
+# process.review_finalized = True
+# process.save()
+#
+# # Schedule next review
+# self.schedule_next_review(review)
+#
+# # Send completion notifications
+# self.notify_review_completion(review)
+#
+# def end_performance_review(self, activation):
+# """End the performance review workflow"""
+# process = activation.process
+#
+# # Generate review summary report
+# self.generate_review_summary(process.performance_review)
+#
+# # Helper methods
+# def notify_review_start(self, review):
+# """Notify employee and manager of review start"""
+# # Notify employee
+# if review.employee.email:
+# send_mail(
+# subject='Performance Review Started',
+# message=f'Your {review.get_review_type_display()} has been initiated.',
+# from_email='hr@hospital.com',
+# recipient_list=[review.employee.email],
+# fail_silently=True
+# )
+#
+# # Notify manager
+# if review.employee.manager and review.employee.manager.email:
+# send_mail(
+# subject=f'Performance Review: {review.employee.get_full_name()}',
+# message=f'Performance review for {review.employee.get_full_name()} has started.',
+# from_email='hr@hospital.com',
+# recipient_list=[review.employee.manager.email],
+# fail_silently=True
+# )
+#
+# def schedule_next_review(self, review):
+# """Schedule next performance review"""
+# if review.review_type == 'ANNUAL':
+# # Schedule next annual review
+# next_review_date = review.review_date + timezone.timedelta(days=365)
+#
+# PerformanceReview.objects.create(
+# employee=review.employee,
+# review_period_start=review.review_period_end + timezone.timedelta(days=1),
+# review_period_end=next_review_date,
+# review_date=next_review_date,
+# review_type='ANNUAL',
+# status='DRAFT'
+# )
+#
+# def notify_review_completion(self, review):
+# """Notify relevant parties of review completion"""
+# # Notify employee
+# if review.employee.email:
+# send_mail(
+# subject='Performance Review Complete',
+# message=f'Your {review.get_review_type_display()} has been completed.',
+# from_email='hr@hospital.com',
+# recipient_list=[review.employee.email],
+# fail_silently=True
+# )
+#
+# # Notify HR
+# hr_staff = User.objects.filter(groups__name='HR Staff')
+# for staff in hr_staff:
+# send_mail(
+# subject=f'Performance Review Complete: {review.employee.get_full_name()}',
+# message=f'Performance review for {review.employee.get_full_name()} has been completed.',
+# from_email='hr@hospital.com',
+# recipient_list=[staff.email],
+# fail_silently=True
+# )
+#
+# def generate_review_summary(self, review):
+# """Generate performance review summary report"""
+# # This would generate a comprehensive review report
+# pass
+#
+#
+# class TrainingProcess(Process):
+# """
+# Viewflow process model for training programs
+# """
+# training_record = ModelField(TrainingRecord, help_text='Associated training record')
+#
+# # Process status tracking
+# training_needs_assessed = models.BooleanField(default=False)
+# training_scheduled = models.BooleanField(default=False)
+# training_delivered = models.BooleanField(default=False)
+# training_evaluated = models.BooleanField(default=False)
+# certification_issued = models.BooleanField(default=False)
+# follow_up_scheduled = models.BooleanField(default=False)
+#
+# class Meta:
+# verbose_name = 'Training Process'
+# verbose_name_plural = 'Training Processes'
+#
+#
+# class TrainingFlow(Flow):
+# """
+# Training Workflow
+#
+# This flow manages training programs including needs assessment,
+# scheduling, delivery, evaluation, and certification.
+# """
+#
+# process_class = TrainingProcess
+#
+# # Flow definition
+# start = (
+# flow_func(this.start_training)
+# .Next(this.assess_training_needs)
+# )
+#
+# assess_training_needs = (
+# flow_view(TrainingNeedsAssessmentView)
+# .Permission('hr.can_assess_training_needs')
+# .Next(this.schedule_training)
+# )
+#
+# schedule_training = (
+# flow_view(TrainingSchedulingView)
+# .Permission('hr.can_schedule_training')
+# .Next(this.deliver_training)
+# )
+#
+# deliver_training = (
+# flow_view(TrainingDeliveryView)
+# .Permission('hr.can_deliver_training')
+# .Next(this.evaluate_training)
+# )
+#
+# evaluate_training = (
+# flow_view(TrainingEvaluationView)
+# .Permission('hr.can_evaluate_training')
+# .Next(this.issue_certification)
+# )
+#
+# issue_certification = (
+# flow_func(this.process_certification)
+# .Next(this.schedule_follow_up)
+# )
+#
+# schedule_follow_up = (
+# flow_func(this.setup_follow_up)
+# .Next(this.finalize_training)
+# )
+#
+# finalize_training = (
+# flow_func(this.complete_training)
+# .Next(this.end)
+# )
+#
+# end = flow_func(this.end_training)
+#
+# # Flow functions
+# def start_training(self, activation):
+# """Initialize the training process"""
+# process = activation.process
+# training = process.training_record
+#
+# # Update training status
+# training.status = 'SCHEDULED'
+# training.save()
+#
+# # Notify employee and manager
+# self.notify_training_start(training)
+#
+# def process_certification(self, activation):
+# """Process certification if training passed"""
+# process = activation.process
+# training = process.training_record
+#
+# if training.passed and training.training_type == 'CERTIFICATION':
+# # Generate certificate number
+# training.certificate_number = self.generate_certificate_number()
+# training.save()
+#
+# process.certification_issued = True
+# process.save()
+#
+# # Notify employee of certification
+# self.notify_certification_issued(training)
+#
+# def setup_follow_up(self, activation):
+# """Setup follow-up training if needed"""
+# process = activation.process
+# training = process.training_record
+#
+# # Schedule follow-up based on training type
+# if training.training_type in ['CERTIFICATION', 'MANDATORY']:
+# if training.expiry_date:
+# # Schedule renewal training
+# renewal_date = training.expiry_date - timezone.timedelta(days=30)
+# self.schedule_renewal_training(training, renewal_date)
+#
+# process.follow_up_scheduled = True
+# process.save()
+#
+# def complete_training(self, activation):
+# """Finalize the training process"""
+# process = activation.process
+# training = process.training_record
+#
+# # Update training status
+# if training.passed:
+# training.status = 'COMPLETED'
+# else:
+# training.status = 'FAILED'
+#
+# training.completion_date = timezone.now().date()
+# training.save()
+#
+# # Send completion notifications
+# self.notify_training_completion(training)
+#
+# def end_training(self, activation):
+# """End the training workflow"""
+# process = activation.process
+#
+# # Generate training summary report
+# self.generate_training_summary(process.training_record)
+#
+# # Helper methods
+# def notify_training_start(self, training):
+# """Notify employee and manager of training start"""
+# # Notify employee
+# if training.employee.email:
+# send_mail(
+# subject=f'Training Scheduled: {training.training_name}',
+# message=f'Your training "{training.training_name}" has been scheduled for {training.training_date}.',
+# from_email='hr@hospital.com',
+# recipient_list=[training.employee.email],
+# fail_silently=True
+# )
+#
+# # Notify manager
+# if training.employee.manager and training.employee.manager.email:
+# send_mail(
+# subject=f'Employee Training: {training.employee.get_full_name()}',
+# message=f'{training.employee.get_full_name()} has training scheduled: {training.training_name}.',
+# from_email='hr@hospital.com',
+# recipient_list=[training.employee.manager.email],
+# fail_silently=True
+# )
+#
+# def generate_certificate_number(self):
+# """Generate unique certificate number"""
+# from django.utils.crypto import get_random_string
+# return f"CERT{timezone.now().strftime('%Y%m%d')}{get_random_string(4, '0123456789')}"
+#
+# def notify_certification_issued(self, training):
+# """Notify employee of certification"""
+# if training.employee.email:
+# send_mail(
+# subject=f'Certification Issued: {training.training_name}',
+# message=f'Congratulations! You have been certified in {training.training_name}. Certificate #: {training.certificate_number}',
+# from_email='hr@hospital.com',
+# recipient_list=[training.employee.email],
+# fail_silently=True
+# )
+#
+# def schedule_renewal_training(self, training, renewal_date):
+# """Schedule renewal training"""
+# TrainingRecord.objects.create(
+# employee=training.employee,
+# training_name=f"{training.training_name} - Renewal",
+# training_type=training.training_type,
+# training_date=renewal_date,
+# status='SCHEDULED'
+# )
+#
+# def notify_training_completion(self, training):
+# """Notify relevant parties of training completion"""
+# # Notify employee
+# if training.employee.email:
+# status_text = "completed successfully" if training.passed else "not passed"
+# send_mail(
+# subject=f'Training {status_text.title()}: {training.training_name}',
+# message=f'Your training "{training.training_name}" has been {status_text}.',
+# from_email='hr@hospital.com',
+# recipient_list=[training.employee.email],
+# fail_silently=True
+# )
+#
+# def generate_training_summary(self, training):
+# """Generate training summary report"""
+# # This would generate a comprehensive training report
+# pass
+#
+#
+# class ComplianceTrackingProcess(Process):
+# """
+# Viewflow process model for compliance tracking
+# """
+# employee_id = CharField(max_length=50, help_text='Employee identifier')
+# compliance_type = CharField(max_length=20, help_text='Type of compliance')
+#
+# # Process status tracking
+# compliance_checked = models.BooleanField(default=False)
+# deficiencies_identified = models.BooleanField(default=False)
+# corrective_actions_planned = models.BooleanField(default=False)
+# actions_implemented = models.BooleanField(default=False)
+# compliance_verified = models.BooleanField(default=False)
+#
+# class Meta:
+# verbose_name = 'Compliance Tracking Process'
+# verbose_name_plural = 'Compliance Tracking Processes'
+#
+#
+# class ComplianceTrackingFlow(Flow):
+# """
+# Compliance Tracking Workflow
+#
+# This flow manages compliance tracking including monitoring,
+# deficiency identification, and corrective actions.
+# """
+#
+# process_class = ComplianceTrackingProcess
+#
+# # Flow definition
+# start = (
+# flow_func(this.start_compliance_tracking)
+# .Next(this.check_compliance)
+# )
+#
+# check_compliance = (
+# flow_func(this.monitor_compliance)
+# .Next(this.identify_deficiencies)
+# )
+#
+# identify_deficiencies = (
+# flow_func(this.assess_deficiencies)
+# .Next(this.plan_corrective_actions)
+# )
+#
+# plan_corrective_actions = (
+# flow_view(CorrectiveActionPlanningView)
+# .Permission('hr.can_plan_corrective_actions')
+# .Next(this.implement_actions)
+# )
+#
+# implement_actions = (
+# flow_view(CorrectiveActionImplementationView)
+# .Permission('hr.can_implement_corrective_actions')
+# .Next(this.verify_compliance)
+# )
+#
+# verify_compliance = (
+# flow_func(this.validate_compliance)
+# .Next(this.finalize_compliance)
+# )
+#
+# finalize_compliance = (
+# flow_func(this.complete_compliance_tracking)
+# .Next(this.end)
+# )
+#
+# end = flow_func(this.end_compliance_tracking)
+#
+# # Flow functions
+# def start_compliance_tracking(self, activation):
+# """Initialize the compliance tracking process"""
+# process = activation.process
+#
+# # Log compliance check initiation
+# self.log_compliance_check(process.employee_id, process.compliance_type)
+#
+# def monitor_compliance(self, activation):
+# """Monitor employee compliance"""
+# process = activation.process
+#
+# # Check compliance status
+# compliance_status = self.check_employee_compliance(process.employee_id, process.compliance_type)
+#
+# process.compliance_checked = True
+# process.save()
+#
+# if not compliance_status:
+# # Alert of compliance issues
+# self.alert_compliance_issues(process.employee_id, process.compliance_type)
+#
+# def assess_deficiencies(self, activation):
+# """Assess compliance deficiencies"""
+# process = activation.process
+#
+# # Identify specific deficiencies
+# deficiencies = self.identify_compliance_deficiencies(process.employee_id, process.compliance_type)
+#
+# if deficiencies:
+# process.deficiencies_identified = True
+# process.save()
+#
+# # Notify relevant parties
+# self.notify_compliance_deficiencies(process.employee_id, deficiencies)
+#
+# def validate_compliance(self, activation):
+# """Validate compliance after corrective actions"""
+# process = activation.process
+#
+# # Re-check compliance
+# compliance_status = self.check_employee_compliance(process.employee_id, process.compliance_type)
+#
+# if compliance_status:
+# process.compliance_verified = True
+# process.save()
+# else:
+# # Escalate if still non-compliant
+# self.escalate_compliance_issue(process.employee_id, process.compliance_type)
+#
+# def complete_compliance_tracking(self, activation):
+# """Finalize the compliance tracking process"""
+# process = activation.process
+#
+# # Generate compliance report
+# self.generate_compliance_report(process.employee_id, process.compliance_type)
+#
+# def end_compliance_tracking(self, activation):
+# """End the compliance tracking workflow"""
+# process = activation.process
+#
+# # Archive compliance tracking
+# self.archive_compliance_tracking(process.employee_id, process.compliance_type)
+#
+# # Helper methods
+# def log_compliance_check(self, employee_id, compliance_type):
+# """Log compliance check"""
+# # This would log the compliance check
+# pass
+#
+# def check_employee_compliance(self, employee_id, compliance_type):
+# """Check employee compliance status"""
+# # This would check compliance status
+# return True
+#
+# def alert_compliance_issues(self, employee_id, compliance_type):
+# """Alert of compliance issues"""
+# # This would send compliance alerts
+# pass
+#
+# def identify_compliance_deficiencies(self, employee_id, compliance_type):
+# """Identify specific compliance deficiencies"""
+# # This would identify deficiencies
+# return []
+#
+# def notify_compliance_deficiencies(self, employee_id, deficiencies):
+# """Notify of compliance deficiencies"""
+# # This would send deficiency notifications
+# pass
+#
+# def escalate_compliance_issue(self, employee_id, compliance_type):
+# """Escalate compliance issue"""
+# # This would escalate the issue
+# pass
+#
+# def generate_compliance_report(self, employee_id, compliance_type):
+# """Generate compliance report"""
+# # This would generate compliance report
+# pass
+#
+# def archive_compliance_tracking(self, employee_id, compliance_type):
+# """Archive compliance tracking"""
+# # This would archive the tracking
+# pass
+#
+#
+# # Celery tasks for background processing
+# @celery.job
+# def auto_schedule_performance_reviews():
+# """Background task to automatically schedule performance reviews"""
+# try:
+# # This would schedule upcoming reviews
+# return True
+# except Exception:
+# return False
+#
+#
+# @celery.job
+# def monitor_training_expiry():
+# """Background task to monitor training and certification expiry"""
+# try:
+# # This would monitor expiring certifications
+# return True
+# except Exception:
+# return False
+#
+#
+# @celery.job
+# def generate_hr_compliance_report():
+# """Background task to generate HR compliance reports"""
+# try:
+# # This would generate compliance reports
+# return True
+# except Exception:
+# return False
+#
+#
+# @celery.job
+# def auto_assign_mandatory_training():
+# """Background task to automatically assign mandatory training"""
+# try:
+# # This would assign mandatory training
+# return True
+# except Exception:
+# return False
+#
diff --git a/hr/migrations/0002_trainingrecord_is_certified.py b/hr/migrations/0002_trainingrecord_is_certified.py
new file mode 100644
index 00000000..e80a416d
--- /dev/null
+++ b/hr/migrations/0002_trainingrecord_is_certified.py
@@ -0,0 +1,18 @@
+# Generated by Django 5.2.4 on 2025-09-07 14:29
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ("hr", "0001_initial"),
+ ]
+
+ operations = [
+ migrations.AddField(
+ model_name="trainingrecord",
+ name="is_certified",
+ field=models.BooleanField(default=False, help_text="Training is certified"),
+ ),
+ ]
diff --git a/hr/migrations/__pycache__/0002_trainingrecord_is_certified.cpython-312.pyc b/hr/migrations/__pycache__/0002_trainingrecord_is_certified.cpython-312.pyc
new file mode 100644
index 00000000..5d772d29
Binary files /dev/null and b/hr/migrations/__pycache__/0002_trainingrecord_is_certified.cpython-312.pyc differ
diff --git a/hr/models.py b/hr/models.py
index f0a1c9df..a1240a65 100644
--- a/hr/models.py
+++ b/hr/models.py
@@ -11,6 +11,8 @@ from django.conf import settings
from datetime import timedelta, datetime, date, time
from decimal import Decimal
import json
+from django.core.exceptions import ValidationError
+
class Employee(models.Model):
@@ -157,7 +159,13 @@ class Employee(models.Model):
null=True,
help_text='Country'
)
-
+ national_id = models.CharField(
+ max_length=10,
+ blank=True,
+ null=True,
+ unique=True,
+ help_text='National ID'
+ )
# Personal Details
date_of_birth = models.DateField(
blank=True,
@@ -391,12 +399,19 @@ class Department(models.Model):
"""
Department model for organizational structure.
"""
-
+ DEPARTMENT_TYPE_CHOICES = [
+ ('CLINICAL', 'Clinical'),
+ ('ADMINISTRATIVE', 'Administrative'),
+ ('SUPPORT', 'Support'),
+ ('ANCILLARY', 'Ancillary'),
+ ('EXECUTIVE', 'Executive'),
+ ]
+
# Tenant relationship
tenant = models.ForeignKey(
'core.Tenant',
on_delete=models.CASCADE,
- related_name='hr_departments',
+ related_name='departments',
help_text='Organization tenant'
)
@@ -409,7 +424,7 @@ class Department(models.Model):
)
department_code = models.CharField(
max_length=20,
- help_text='Department code'
+ help_text='Department code (e.g., CARD, EMER, SURG)'
)
name = models.CharField(
max_length=100,
@@ -424,13 +439,7 @@ class Department(models.Model):
# Department Type
department_type = models.CharField(
max_length=20,
- choices=[
- ('CLINICAL', 'Clinical'),
- ('ADMINISTRATIVE', 'Administrative'),
- ('SUPPORT', 'Support'),
- ('ANCILLARY', 'Ancillary'),
- ('EXECUTIVE', 'Executive'),
- ],
+ choices=DEPARTMENT_TYPE_CHOICES,
help_text='Department type'
)
@@ -440,7 +449,7 @@ class Department(models.Model):
on_delete=models.CASCADE,
null=True,
blank=True,
- related_name='child_departments',
+ related_name='sub_departments',
help_text='Parent department'
)
@@ -453,6 +462,24 @@ class Department(models.Model):
related_name='headed_departments',
help_text='Department head'
)
+ # Contact Information
+ phone = models.CharField(
+ max_length=20,
+ blank=True,
+ null=True,
+ help_text='Department phone number'
+ )
+ extension = models.CharField(
+ max_length=10,
+ blank=True,
+ null=True,
+ help_text='Phone extension'
+ )
+ email = models.EmailField(
+ blank=True,
+ null=True,
+ help_text='Department email'
+ )
# Budget Information
annual_budget = models.DecimalField(
@@ -468,7 +495,10 @@ class Department(models.Model):
null=True,
help_text='Cost center code'
)
-
+ authorized_positions = models.PositiveIntegerField(
+ default=0,
+ help_text='Number of authorized positions'
+ )
# Location Information
location = models.CharField(
max_length=100,
@@ -477,11 +507,42 @@ class Department(models.Model):
help_text='Department location'
)
- # Department Status
+ # Operational Information
is_active = models.BooleanField(
default=True,
help_text='Department is active'
)
+ is_24_hour = models.BooleanField(
+ default=False,
+ help_text='Department operates 24 hours'
+ )
+ operating_hours = models.JSONField(
+ default=dict,
+ blank=True,
+ help_text='Operating hours by day of week'
+ )
+
+ # Quality and Compliance
+ accreditation_required = models.BooleanField(
+ default=False,
+ help_text='Department requires special accreditation'
+ )
+ accreditation_body = models.CharField(
+ max_length=100,
+ blank=True,
+ null=True,
+ help_text='Accrediting body (e.g., Joint Commission, CAP)'
+ )
+ last_inspection_date = models.DateField(
+ blank=True,
+ null=True,
+ help_text='Last inspection date'
+ )
+ next_inspection_date = models.DateField(
+ blank=True,
+ null=True,
+ help_text='Next scheduled inspection date'
+ )
# Notes
notes = models.TextField(
@@ -517,7 +578,14 @@ class Department(models.Model):
def __str__(self):
return f"{self.department_code} - {self.name}"
-
+
+ @property
+ def full_name(self):
+ """Return full department name with parent if applicable"""
+ if self.parent_department:
+ return f"{self.parent_department.name} - {self.name}"
+ return self.name
+
@property
def employee_count(self):
"""
@@ -532,12 +600,33 @@ class Department(models.Model):
"""
return sum(emp.fte_percentage for emp in self.employees.filter(employment_status='ACTIVE')) / 100
+ @property
+ def staffing_percentage(self):
+ """Calculate current staffing percentage"""
+ if self.authorized_positions > 0:
+ return (self.employee_count / self.authorized_positions) * 100
+ return 0
+
+ def get_all_sub_departments(self):
+ """Get all sub-departments recursively"""
+ sub_departments = []
+ for sub_dept in self.sub_departments.all():
+ sub_departments.append(sub_dept)
+ sub_departments.extend(sub_dept.get_all_sub_departments())
+ return sub_departments
+
class Schedule(models.Model):
"""
Schedule model for employee work schedules.
"""
-
+ SCHEDULE_TYPE_CHOICES = [
+ ('REGULAR', 'Regular Schedule'),
+ ('ROTATING', 'Rotating Schedule'),
+ ('FLEXIBLE', 'Flexible Schedule'),
+ ('ON_CALL', 'On-Call Schedule'),
+ ('TEMPORARY', 'Temporary Schedule'),
+ ]
# Employee relationship
employee = models.ForeignKey(
Employee,
@@ -566,13 +655,7 @@ class Schedule(models.Model):
# Schedule Type
schedule_type = models.CharField(
max_length=20,
- choices=[
- ('REGULAR', 'Regular Schedule'),
- ('ROTATING', 'Rotating Schedule'),
- ('FLEXIBLE', 'Flexible Schedule'),
- ('ON_CALL', 'On-Call Schedule'),
- ('TEMPORARY', 'Temporary Schedule'),
- ],
+ choices=SCHEDULE_TYPE_CHOICES,
help_text='Schedule type'
)
@@ -668,7 +751,23 @@ class ScheduleAssignment(models.Model):
"""
Schedule assignment model for specific shift assignments.
"""
-
+ SHIFT_TYPE_CHOICES = [
+ ('DAY', 'Day Shift'),
+ ('EVENING', 'Evening Shift'),
+ ('NIGHT', 'Night Shift'),
+ ('WEEKEND', 'Weekend Shift'),
+ ('HOLIDAY', 'Holiday Shift'),
+ ('ON_CALL', 'On-Call'),
+ ('OVERTIME', 'Overtime'),
+ ]
+ STATUS_CHOICES = [
+ ('SCHEDULED', 'Scheduled'),
+ ('CONFIRMED', 'Confirmed'),
+ ('COMPLETED', 'Completed'),
+ ('CANCELLED', 'Cancelled'),
+ ('NO_SHOW', 'No Show'),
+ ]
+
# Schedule relationship
schedule = models.ForeignKey(
Schedule,
@@ -699,15 +798,7 @@ class ScheduleAssignment(models.Model):
# Shift Information
shift_type = models.CharField(
max_length=20,
- choices=[
- ('DAY', 'Day Shift'),
- ('EVENING', 'Evening Shift'),
- ('NIGHT', 'Night Shift'),
- ('WEEKEND', 'Weekend Shift'),
- ('HOLIDAY', 'Holiday Shift'),
- ('ON_CALL', 'On-Call'),
- ('OVERTIME', 'Overtime'),
- ],
+ choices=SHIFT_TYPE_CHOICES,
help_text='Shift type'
)
@@ -730,13 +821,7 @@ class ScheduleAssignment(models.Model):
# Assignment Status
status = models.CharField(
max_length=20,
- choices=[
- ('SCHEDULED', 'Scheduled'),
- ('CONFIRMED', 'Confirmed'),
- ('COMPLETED', 'Completed'),
- ('CANCELLED', 'Cancelled'),
- ('NO_SHOW', 'No Show'),
- ],
+ choices=STATUS_CHOICES,
default='SCHEDULED',
help_text='Assignment status'
)
@@ -812,7 +897,25 @@ class TimeEntry(models.Model):
"""
Time entry model for tracking actual work hours.
"""
-
+ ENTRY_TYPE_CHOICES = [
+ ('REGULAR', 'Regular Time'),
+ ('OVERTIME', 'Overtime'),
+ ('HOLIDAY', 'Holiday'),
+ ('VACATION', 'Vacation'),
+ ('SICK', 'Sick Leave'),
+ ('PERSONAL', 'Personal Time'),
+ ('BEREAVEMENT', 'Bereavement'),
+ ('JURY_DUTY', 'Jury Duty'),
+ ('TRAINING', 'Training'),
+ ]
+ STATUS_CHOICES = [
+ ('DRAFT', 'Draft'),
+ ('SUBMITTED', 'Submitted'),
+ ('APPROVED', 'Approved'),
+ ('REJECTED', 'Rejected'),
+ ('PAID', 'Paid'),
+ ]
+
# Employee relationship
employee = models.ForeignKey(
Employee,
@@ -889,17 +992,7 @@ class TimeEntry(models.Model):
# Entry Type
entry_type = models.CharField(
max_length=20,
- choices=[
- ('REGULAR', 'Regular Time'),
- ('OVERTIME', 'Overtime'),
- ('HOLIDAY', 'Holiday'),
- ('VACATION', 'Vacation'),
- ('SICK', 'Sick Leave'),
- ('PERSONAL', 'Personal Time'),
- ('BEREAVEMENT', 'Bereavement'),
- ('JURY_DUTY', 'Jury Duty'),
- ('TRAINING', 'Training'),
- ],
+ choices=ENTRY_TYPE_CHOICES,
default='REGULAR',
help_text='Entry type'
)
@@ -938,13 +1031,7 @@ class TimeEntry(models.Model):
# Entry Status
status = models.CharField(
max_length=20,
- choices=[
- ('DRAFT', 'Draft'),
- ('SUBMITTED', 'Submitted'),
- ('APPROVED', 'Approved'),
- ('REJECTED', 'Rejected'),
- ('PAID', 'Paid'),
- ],
+ choices=STATUS_CHOICES,
default='DRAFT',
help_text='Entry status'
)
@@ -1024,7 +1111,21 @@ class PerformanceReview(models.Model):
"""
Performance review model for employee evaluations.
"""
-
+ REVIEW_TYPE_CHOICES = [
+ ('ANNUAL', 'Annual Review'),
+ ('PROBATIONARY', 'Probationary Review'),
+ ('MID_YEAR', 'Mid-Year Review'),
+ ('PROJECT', 'Project Review'),
+ ('DISCIPLINARY', 'Disciplinary Review'),
+ ('PROMOTION', 'Promotion Review'),
+ ]
+ STATUS_CHOICES = [
+ ('DRAFT', 'Draft'),
+ ('IN_PROGRESS', 'In Progress'),
+ ('COMPLETED', 'Completed'),
+ ('ACKNOWLEDGED', 'Acknowledged by Employee'),
+ ('DISPUTED', 'Disputed'),
+ ]
# Employee relationship
employee = models.ForeignKey(
Employee,
@@ -1055,14 +1156,7 @@ class PerformanceReview(models.Model):
# Review Type
review_type = models.CharField(
max_length=20,
- choices=[
- ('ANNUAL', 'Annual Review'),
- ('PROBATIONARY', 'Probationary Review'),
- ('MID_YEAR', 'Mid-Year Review'),
- ('PROJECT', 'Project Review'),
- ('DISCIPLINARY', 'Disciplinary Review'),
- ('PROMOTION', 'Promotion Review'),
- ],
+ choices=REVIEW_TYPE_CHOICES,
help_text='Review type'
)
@@ -1146,13 +1240,7 @@ class PerformanceReview(models.Model):
# Review Status
status = models.CharField(
max_length=20,
- choices=[
- ('DRAFT', 'Draft'),
- ('IN_PROGRESS', 'In Progress'),
- ('COMPLETED', 'Completed'),
- ('ACKNOWLEDGED', 'Acknowledged by Employee'),
- ('DISPUTED', 'Disputed'),
- ],
+ choices=STATUS_CHOICES,
default='DRAFT',
help_text='Review status'
)
@@ -1204,7 +1292,26 @@ class TrainingRecord(models.Model):
"""
Training record model for employee training and certifications.
"""
-
+ TRAINING_TYPE_CHOICES = [
+ ('ORIENTATION', 'Orientation'),
+ ('MANDATORY', 'Mandatory Training'),
+ ('CONTINUING_ED', 'Continuing Education'),
+ ('CERTIFICATION', 'Certification'),
+ ('SKILLS', 'Skills Training'),
+ ('SAFETY', 'Safety Training'),
+ ('COMPLIANCE', 'Compliance Training'),
+ ('LEADERSHIP', 'Leadership Development'),
+ ('TECHNICAL', 'Technical Training'),
+ ('OTHER', 'Other'),
+ ]
+ STATUS_CHOICES = [
+ ('SCHEDULED', 'Scheduled'),
+ ('IN_PROGRESS', 'In Progress'),
+ ('COMPLETED', 'Completed'),
+ ('CANCELLED', 'Cancelled'),
+ ('NO_SHOW', 'No Show'),
+ ('FAILED', 'Failed'),
+ ]
# Employee relationship
employee = models.ForeignKey(
Employee,
@@ -1229,25 +1336,14 @@ class TrainingRecord(models.Model):
null=True,
help_text='Training description'
)
-
+
# Training Type
training_type = models.CharField(
max_length=20,
- choices=[
- ('ORIENTATION', 'Orientation'),
- ('MANDATORY', 'Mandatory Training'),
- ('CONTINUING_ED', 'Continuing Education'),
- ('CERTIFICATION', 'Certification'),
- ('SKILLS', 'Skills Training'),
- ('SAFETY', 'Safety Training'),
- ('COMPLIANCE', 'Compliance Training'),
- ('LEADERSHIP', 'Leadership Development'),
- ('TECHNICAL', 'Technical Training'),
- ('OTHER', 'Other'),
- ],
+ choices=TRAINING_TYPE_CHOICES,
help_text='Training type'
)
-
+
# Training Provider
training_provider = models.CharField(
max_length=200,
@@ -1261,7 +1357,7 @@ class TrainingRecord(models.Model):
null=True,
help_text='Instructor name'
)
-
+
# Training Dates
training_date = models.DateField(
help_text='Training date'
@@ -1294,14 +1390,7 @@ class TrainingRecord(models.Model):
# Training Status
status = models.CharField(
max_length=20,
- choices=[
- ('SCHEDULED', 'Scheduled'),
- ('IN_PROGRESS', 'In Progress'),
- ('COMPLETED', 'Completed'),
- ('CANCELLED', 'Cancelled'),
- ('NO_SHOW', 'No Show'),
- ('FAILED', 'Failed'),
- ],
+ choices=STATUS_CHOICES,
default='SCHEDULED',
help_text='Training status'
)
@@ -1318,7 +1407,10 @@ class TrainingRecord(models.Model):
default=False,
help_text='Training passed'
)
-
+ is_certified = models.BooleanField(
+ default=False,
+ help_text='Training is certified'
+ )
# Certification Information
certificate_number = models.CharField(
max_length=50,
@@ -1409,3 +1501,411 @@ class TrainingRecord(models.Model):
return (self.expiry_date - date.today()).days <= 30
return False
+
+# class TrainingPrograms(models.Model):
+# PROGRAM_TYPE_CHOICES = [
+# ('ORIENTATION', 'Orientation'),
+# ('MANDATORY', 'Mandatory Training'),
+# ('CONTINUING_ED', 'Continuing Education'),
+# ('CERTIFICATION', 'Certification'),
+# ('SKILLS', 'Skills Training'),
+# ('SAFETY', 'Safety Training'),
+# ('COMPLIANCE', 'Compliance Training'),
+# ('LEADERSHIP', 'Leadership Development'),
+# ('TECHNICAL', 'Technical Training'),
+# ('OTHER', 'Other'),
+# ]
+#
+# # Multi-tenancy
+# tenant = models.ForeignKey(
+# 'core.Tenant', on_delete=models.CASCADE, related_name='training_programs'
+# )
+#
+# program_id = models.UUIDField(default=uuid.uuid4, unique=True, editable=False)
+# name = models.CharField(max_length=200)
+# description = models.TextField(blank=True, null=True)
+# program_type = models.CharField(max_length=20, choices=PROGRAM_TYPE_CHOICES)
+#
+# # Provider/Instructor at the program (defaults; sessions can override)
+# program_provider = models.CharField(max_length=200, blank=True, null=True)
+# default_instructor = models.ForeignKey(
+# Employee, on_delete=models.SET_NULL, null=True, blank=True,
+# related_name='default_instructor_programs',
+# help_text='Default instructor; sessions may override'
+# )
+#
+# # Optional “program window” (e.g., for long initiatives)
+# start_date = models.DateField(help_text='Program start date', blank=True, null=True)
+# end_date = models.DateField(help_text='Program end date', blank=True, null=True)
+#
+# duration_hours = models.DecimalField(max_digits=5, decimal_places=2,
+# default=Decimal('0.00'))
+# cost = models.DecimalField(max_digits=10, decimal_places=2,
+# default=Decimal('0.00'))
+# is_certified = models.BooleanField(default=False)
+#
+# # Renewal/expiry policy (applies if is_certified)
+# validity_days = models.PositiveIntegerField(
+# blank=True, null=True,
+# help_text='Days certificate is valid from completion (e.g., 365).'
+# )
+# notify_before_days = models.PositiveIntegerField(
+# blank=True, null=True,
+# help_text='Days before expiry to flag for renewal.'
+# )
+#
+# # Metadata
+# created_at = models.DateTimeField(auto_now_add=True)
+# updated_at = models.DateTimeField(auto_now=True)
+# created_by = models.ForeignKey(
+# settings.AUTH_USER_MODEL, on_delete=models.SET_NULL,
+# null=True, blank=True, related_name='created_training_programs'
+# )
+#
+# class Meta:
+# db_table = 'hr_training_program'
+# ordering = ['name']
+# unique_together = [('tenant', 'name')]
+# indexes = [
+# models.Index(fields=['tenant', 'program_type']),
+# models.Index(fields=['tenant', 'is_certified']),
+# ]
+#
+# def clean(self):
+# if self.start_date and self.end_date and self.end_date < self.start_date:
+# raise ValidationError(_('Program end_date cannot be before start_date.'))
+# if self.is_certified and not self.validity_days:
+# # Not hard error—could be open-ended—but warn as best practice.
+# pass
+#
+# def __str__(self):
+# return f'{self.name} ({self.get_program_type_display()})'
+#
+#
+# class ProgramModule(models.Model):
+# """Optional content structure for a program."""
+# program = models.ForeignKey(
+# TrainingPrograms, on_delete=models.CASCADE, related_name='modules'
+# )
+# title = models.CharField(max_length=200)
+# order = models.PositiveIntegerField(default=1)
+# hours = models.DecimalField(max_digits=5, decimal_places=2,
+# default=Decimal('0.00'))
+#
+# class Meta:
+# db_table = 'hr_training_program_module'
+# ordering = ['program', 'order']
+# unique_together = [('program', 'order')]
+# indexes = [models.Index(fields=['program', 'order'])]
+#
+# def __str__(self):
+# return f'{self.program.name} · {self.order}. {self.title}'
+#
+#
+# class ProgramPrerequisite(models.Model):
+# """A program may require completion of other program(s)."""
+# program = models.ForeignKey(
+# TrainingPrograms, on_delete=models.CASCADE, related_name='prerequisites'
+# )
+# required_program = models.ForeignKey(
+# TrainingPrograms, on_delete=models.CASCADE, related_name='unlocking_programs'
+# )
+#
+# class Meta:
+# db_table = 'hr_training_program_prerequisite'
+# unique_together = [('program', 'required_program')]
+#
+# def clean(self):
+# if self.program_id == self.required_program_id:
+# raise ValidationError(_('Program cannot require itself.'))
+#
+#
+# class TrainingSession(models.Model):
+# """
+# A scheduled run of a program (cohort/class).
+# """
+# DELIVERY_CHOICES = [
+# ('IN_PERSON', 'In-person'),
+# ('VIRTUAL', 'Virtual'),
+# ('HYBRID', 'Hybrid'),
+# ('SELF_PACED', 'Self-paced'),
+# ]
+#
+# tenant = models.ForeignKey(
+# Tenant, on_delete=models.CASCADE, related_name='training_sessions'
+# )
+# session_id = models.UUIDField(default=uuid.uuid4, unique=True, editable=False)
+# program = models.ForeignKey(
+# TrainingPrograms, on_delete=models.CASCADE, related_name='sessions'
+# )
+# title = models.CharField(
+# max_length=200, blank=True, null=True,
+# help_text='Optional run title; falls back to program name'
+# )
+# instructor = models.ForeignKey(
+# Employee, on_delete=models.SET_NULL, null=True, blank=True,
+# related_name='instructed_sessions'
+# )
+# delivery_method = models.CharField(max_length=12, choices=DELIVERY_CHOICES, default='IN_PERSON')
+#
+# # Schedule
+# start_at = models.DateTimeField()
+# end_at = models.DateTimeField()
+# location = models.CharField(max_length=200, blank=True, null=True)
+# capacity = models.PositiveIntegerField(default=0)
+#
+# # Overrides
+# cost_override = models.DecimalField(max_digits=10, decimal_places=2,
+# blank=True, null=True)
+# hours_override = models.DecimalField(max_digits=5, decimal_places=2,
+# blank=True, null=True)
+#
+# # Metadata
+# created_at = models.DateTimeField(auto_now_add=True)
+# created_by = models.ForeignKey(
+# settings.AUTH_USER_MODEL, on_delete=models.SET_NULL,
+# null=True, blank=True, related_name='created_training_sessions'
+# )
+#
+# class Meta:
+# db_table = 'hr_training_session'
+# ordering = ['-start_at']
+# indexes = [
+# models.Index(fields=['tenant', 'start_at']),
+# models.Index(fields=['tenant', 'program']),
+# ]
+# constraints = [
+# models.CheckConstraint(
+# check=models.Q(end_at__gt=models.F('start_at')),
+# name='session_end_after_start'
+# ),
+# ]
+#
+# def __str__(self):
+# return self.title or f'{self.program.name} @ {self.start_at:%Y-%m-%d}'
+#
+#
+# class TrainingRecord(models.Model):
+# """
+# Enrollment/participation record (renamed semantic, kept class name).
+# Each row = an employee participating in a specific session of a program.
+# """
+# STATUS_CHOICES = [
+# ('SCHEDULED', 'Scheduled'),
+# ('IN_PROGRESS', 'In Progress'),
+# ('COMPLETED', 'Completed'),
+# ('CANCELLED', 'Cancelled'),
+# ('NO_SHOW', 'No Show'),
+# ('FAILED', 'Failed'),
+# ('WAITLISTED', 'Waitlisted'),
+# ]
+#
+# tenant = models.ForeignKey(
+# Tenant, on_delete=models.CASCADE, related_name='training_records'
+# )
+# record_id = models.UUIDField(default=uuid.uuid4, unique=True, editable=False)
+#
+# # Core links
+# employee = models.ForeignKey(
+# Employee, on_delete=models.CASCADE, related_name='training_records'
+# )
+# program = models.ForeignKey(
+# TrainingPrograms, on_delete=models.PROTECT, related_name='training_records'
+# )
+# session = models.ForeignKey(
+# TrainingSession, on_delete=models.PROTECT, related_name='enrollments',
+# help_text='The specific run the employee is enrolled in.'
+# )
+#
+# # Timeline
+# enrolled_at = models.DateTimeField(auto_now_add=True)
+# started_at = models.DateTimeField(blank=True, null=True)
+# completion_date = models.DateField(blank=True, null=True)
+#
+# # Outcomes
+# status = models.CharField(max_length=20, choices=STATUS_CHOICES, default='SCHEDULED')
+# credits_earned = models.DecimalField(max_digits=5, decimal_places=2,
+# default=Decimal('0.00'))
+# score = models.DecimalField(max_digits=5, decimal_places=2, blank=True, null=True)
+# passed = models.BooleanField(default=False)
+#
+# # Notes/Cost
+# notes = models.TextField(blank=True, null=True)
+# cost_paid = models.DecimalField(max_digits=10, decimal_places=2,
+# blank=True, null=True)
+#
+# created_at = models.DateTimeField(auto_now_add=True)
+# updated_at = models.DateTimeField(auto_now=True)
+# created_by = models.ForeignKey(
+# settings.AUTH_USER_MODEL, on_delete=models.SET_NULL,
+# null=True, blank=True, related_name='created_training_records'
+# )
+#
+# class Meta:
+# db_table = 'hr_training_record'
+# verbose_name = 'Training Enrollment'
+# verbose_name_plural = 'Training Enrollments'
+# ordering = ['-enrolled_at']
+# unique_together = [('employee', 'session')]
+# indexes = [
+# models.Index(fields=['tenant', 'employee']),
+# models.Index(fields=['tenant', 'program']),
+# models.Index(fields=['tenant', 'session']),
+# models.Index(fields=['tenant', 'status']),
+# models.Index(fields=['tenant', 'completion_date']),
+# ]
+#
+# def clean(self):
+# # Tenancy alignment
+# if self.program and self.tenant_id != self.program.tenant_id:
+# raise ValidationError(_('Tenant mismatch between record and program.'))
+# if self.session and self.tenant_id != self.session.tenant_id:
+# raise ValidationError(_('Tenant mismatch between record and session.'))
+# if self.employee and self.tenant_id != self.employee.tenant_id:
+# raise ValidationError(_('Tenant mismatch between record and employee.'))
+#
+# # Prevent enrolling into sessions of a different program (shouldn’t happen)
+# if self.session and self.program and self.session.program_id != self.program_id:
+# raise ValidationError(_('Session does not belong to the selected program.'))
+#
+# if self.completion_date and self.status not in ('COMPLETED', 'FAILED'):
+# raise ValidationError(_('Completion date requires status COMPLETED or FAILED.'))
+#
+# def __str__(self):
+# return f'{self.employee} → {self.program.name} ({self.get_status_display()})'
+#
+# # Helper properties
+# @property
+# def hours(self):
+# return self.session.hours_override or self.program.duration_hours
+#
+# @property
+# def effective_cost(self):
+# return self.cost_paid if self.cost_paid is not None else \
+# (self.session.cost_override if self.session.cost_override is not None
+# else self.program.cost)
+#
+# @property
+# def eligible_for_certificate(self):
+# return self.status == 'COMPLETED' and self.passed and self.program.is_certified
+#
+#
+# class SessionAttendance(models.Model):
+# """
+# Optional check-in/out per participant per session (or per day if multi-day).
+# If you want per-day granularity, add a "session_day" field.
+# """
+# ATTENDANCE_STATUS = [
+# ('PRESENT', 'Present'),
+# ('LATE', 'Late'),
+# ('ABSENT', 'Absent'),
+# ('EXCUSED', 'Excused'),
+# ]
+#
+# enrollment = models.ForeignKey(
+# TrainingRecord, on_delete=models.CASCADE, related_name='attendance'
+# )
+# checked_in_at = models.DateTimeField(blank=True, null=True)
+# checked_out_at = models.DateTimeField(blank=True, null=True)
+# status = models.CharField(max_length=10, choices=ATTENDANCE_STATUS, default='PRESENT')
+# notes = models.CharField(max_length=255, blank=True, null=True)
+#
+# class Meta:
+# db_table = 'hr_training_attendance'
+# ordering = ['enrollment_id', 'checked_in_at']
+# indexes = [models.Index(fields=['enrollment'])]
+#
+#
+# class SessionAssessment(models.Model):
+# """
+# Optional evaluation (quiz/exam) tied to an enrollment.
+# """
+# enrollment = models.ForeignKey(
+# TrainingRecord, on_delete=models.CASCADE, related_name='assessments'
+# )
+# name = models.CharField(max_length=200)
+# max_score = models.DecimalField(max_digits=7, decimal_places=2, default=100)
+# score = models.DecimalField(max_digits=7, decimal_places=2, blank=True, null=True)
+# passed = models.BooleanField(default=False)
+# taken_at = models.DateTimeField(blank=True, null=True)
+#
+# class Meta:
+# db_table = 'hr_training_assessment'
+# ordering = ['-taken_at']
+# indexes = [models.Index(fields=['enrollment'])]
+#
+#
+# class TrainingCertificates(models.Model):
+# """
+# Issued certificates on completion.
+# Usually tied to a program and the enrollment that produced it.
+# """
+# tenant = models.ForeignKey(
+# Tenant, on_delete=models.CASCADE, related_name='training_certificates'
+# )
+# certificate_id = models.UUIDField(default=uuid.uuid4, unique=True, editable=False)
+#
+# program = models.ForeignKey(
+# TrainingPrograms, on_delete=models.PROTECT, related_name='certificates'
+# )
+# employee = models.ForeignKey(
+# Employee, on_delete=models.CASCADE, related_name='training_certificates'
+# )
+# enrollment = models.OneToOneField(
+# TrainingRecord, on_delete=models.CASCADE, related_name='certificate',
+# help_text='The enrollment that generated this certificate.'
+# )
+#
+# certificate_name = models.CharField(max_length=200)
+# certificate_number = models.CharField(max_length=50, blank=True, null=True)
+# certification_body = models.CharField(max_length=200, blank=True, null=True)
+# issued_date = models.DateField(auto_now_add=True)
+# expiry_date = models.DateField(blank=True, null=True)
+# file = models.FileField(upload_to='certificates/', blank=True, null=True)
+#
+# created_at = models.DateTimeField(auto_now_add=True)
+# created_by = models.ForeignKey(
+# settings.AUTH_USER_MODEL, on_delete=models.SET_NULL,
+# null=True, blank=True, related_name='created_training_certificates'
+# )
+#
+# class Meta:
+# db_table = 'hr_training_certificate'
+# ordering = ['-issued_date']
+# unique_together = [('employee', 'program', 'enrollment')]
+# indexes = [
+# models.Index(fields=['tenant', 'employee']),
+# models.Index(fields=['tenant', 'program']),
+# models.Index(fields=['tenant', 'expiry_date']),
+# models.Index(fields=['certificate_number']),
+# ]
+#
+# def clean(self):
+# # tenancy alignment
+# if self.program and self.tenant_id != self.program.tenant_id:
+# raise ValidationError(_('Tenant mismatch between certificate and program.'))
+# if self.employee and self.tenant_id != self.employee.tenant_id:
+# raise ValidationError(_('Tenant mismatch between certificate and employee.'))
+# if self.enrollment and self.tenant_id != self.enrollment.tenant_id:
+# raise ValidationError(_('Tenant mismatch between certificate and enrollment.'))
+# if self.enrollment and self.enrollment.program_id != self.program_id:
+# raise ValidationError(_('Enrollment does not belong to this program.'))
+#
+# def __str__(self):
+# return f'{self.certificate_name} - {self.employee}'
+#
+# @property
+# def is_expired(self):
+# return bool(self.expiry_date and self.expiry_date < date.today())
+#
+# @property
+# def days_to_expiry(self):
+# return (self.expiry_date - date.today()).days if self.expiry_date else None
+#
+# @classmethod
+# def compute_expiry(cls, program: TrainingPrograms, issued_on: date) -> date | None:
+# if program.is_certified and program.validity_days:
+# return issued_on + timedelta(days=program.validity_days)
+# return None
+
+
diff --git a/hr/urls.py b/hr/urls.py
index 28f18a0d..f1b272b4 100644
--- a/hr/urls.py
+++ b/hr/urls.py
@@ -65,10 +65,12 @@ urlpatterns = [
path('reviews//', views.PerformanceReviewDetailView.as_view(), name='performance_review_detail'),
path('reviews//update/', views.PerformanceReviewUpdateView.as_view(), name='performance_review_update'),
path('reviews//delete/', views.PerformanceReviewDeleteView.as_view(), name='performance_review_delete'),
+ path('reviews//complete/', views.complete_performance_review, name='complete_performance_review'),
# ============================================================================
# TRAINING RECORD URLS (FULL CRUD - Operational Data)
# ============================================================================
+ path('training-management', views.TrainingManagementView.as_view(), name='training_management'),
path('training/', views.TrainingRecordListView.as_view(), name='training_record_list'),
path('training/create/', views.TrainingRecordCreateView.as_view(), name='training_record_create'),
path('training//', views.TrainingRecordDetailView.as_view(), name='training_record_detail'),
@@ -88,6 +90,7 @@ urlpatterns = [
path('clock-out/', views.clock_out, name='clock_out'),
path('time-entries//approve/', views.approve_time_entry, name='approve_time_entry'),
path('schedules//publish/', views.publish_schedule, name='publish_schedule'),
+
# ============================================================================
# API ENDPOINTS
diff --git a/hr/views.py b/hr/views.py
index ae42ae33..f09cf856 100644
--- a/hr/views.py
+++ b/hr/views.py
@@ -28,10 +28,6 @@ from .forms import (
)
-# ============================================================================
-# DASHBOARD AND OVERVIEW VIEWS
-# ============================================================================
-
class HRDashboardView(LoginRequiredMixin, TemplateView):
"""
Main HR dashboard with comprehensive statistics and recent activity.
@@ -92,10 +88,6 @@ class HRDashboardView(LoginRequiredMixin, TemplateView):
return context
-# ============================================================================
-# EMPLOYEE VIEWS (FULL CRUD - Master Data)
-# ============================================================================
-
class EmployeeListView(LoginRequiredMixin, ListView):
"""
List all employees with filtering and search capabilities.
@@ -236,7 +228,7 @@ class EmployeeDeleteView(LoginRequiredMixin, DeleteView):
Soft delete an employee record (healthcare compliance).
"""
model = Employee
- template_name = 'hr/employee_confirm_delete.html'
+ template_name = 'hr/employees/employee_confirm_delete.html'
success_url = reverse_lazy('hr:employee_list')
def get_queryset(self):
@@ -253,16 +245,12 @@ class EmployeeDeleteView(LoginRequiredMixin, DeleteView):
return redirect(self.success_url)
-# ============================================================================
-# DEPARTMENT VIEWS (FULL CRUD - Master Data)
-# ============================================================================
-
class DepartmentListView(LoginRequiredMixin, ListView):
"""
List all departments with employee counts.
"""
model = Department
- template_name = 'hr/department_list.html'
+ template_name = 'hr/departments/department_list.html'
context_object_name = 'departments'
paginate_by = 20
@@ -286,7 +274,7 @@ class DepartmentDetailView(LoginRequiredMixin, DetailView):
Display detailed information about a specific department.
"""
model = Department
- template_name = 'hr/department_detail.html'
+ template_name = 'hr/departments/department_detail.html'
context_object_name = 'department'
def get_queryset(self):
@@ -316,7 +304,7 @@ class DepartmentCreateView(LoginRequiredMixin, CreateView):
"""
model = Department
form_class = DepartmentForm
- template_name = 'hr/department_form.html'
+ template_name = 'hr/departments/department_form.html'
success_url = reverse_lazy('hr:department_list')
def form_valid(self, form):
@@ -336,7 +324,7 @@ class DepartmentUpdateView(LoginRequiredMixin, UpdateView):
"""
model = Department
form_class = DepartmentForm
- template_name = 'hr/department_form.html'
+ template_name = 'hr/departments/department_form.html'
def get_queryset(self):
return Department.objects.filter(tenant=self.request.user.tenant)
@@ -359,7 +347,7 @@ class DepartmentDeleteView(LoginRequiredMixin, DeleteView):
Delete a department (only if no employees assigned).
"""
model = Department
- template_name = 'hr/department_confirm_delete.html'
+ template_name = 'hr/departments/department_confirm_delete.html'
success_url = reverse_lazy('hr:department_list')
def get_queryset(self):
@@ -377,16 +365,12 @@ class DepartmentDeleteView(LoginRequiredMixin, DeleteView):
return super().delete(request, *args, **kwargs)
-# ============================================================================
-# SCHEDULE VIEWS (LIMITED CRUD - Operational Data)
-# ============================================================================
-
class ScheduleListView(LoginRequiredMixin, ListView):
"""
List all schedules with filtering capabilities.
"""
model = Schedule
- template_name = 'hr/schedule_list.html'
+ template_name = 'hr/schedules/schedule_list.html'
context_object_name = 'schedules'
paginate_by = 20
@@ -414,7 +398,7 @@ class ScheduleDetailView(LoginRequiredMixin, DetailView):
Display detailed information about a specific schedule.
"""
model = Schedule
- template_name = 'hr/schedule_detail.html'
+ template_name = 'hr/schedules/schedule_detail.html'
context_object_name = 'schedule'
def get_queryset(self):
@@ -438,7 +422,7 @@ class ScheduleCreateView(LoginRequiredMixin, CreateView):
"""
model = Schedule
form_class = ScheduleForm
- template_name = 'hr/schedule_form.html'
+ template_name = 'hr/schedules/schedule_form.html'
success_url = reverse_lazy('hr:schedule_list')
def form_valid(self, form):
@@ -458,7 +442,7 @@ class ScheduleUpdateView(LoginRequiredMixin, UpdateView):
"""
model = Schedule
form_class = ScheduleForm
- template_name = 'hr/schedule_form.html'
+ template_name = 'hr/schedules/schedule_form.html'
def get_queryset(self):
return Schedule.objects.filter(employee__tenant=self.request.user.tenant)
@@ -476,16 +460,12 @@ class ScheduleUpdateView(LoginRequiredMixin, UpdateView):
return kwargs
-# ============================================================================
-# SCHEDULE ASSIGNMENT VIEWS (LIMITED CRUD - Operational Data)
-# ============================================================================
-
class ScheduleAssignmentListView(LoginRequiredMixin, ListView):
"""
List all schedule assignments with filtering capabilities.
"""
model = ScheduleAssignment
- template_name = 'hr/schedule_assignment_list.html'
+ template_name = 'hr/assignments/schedule_assignment_list.html'
context_object_name = 'assignments'
paginate_by = 20
@@ -521,7 +501,7 @@ class ScheduleAssignmentCreateView(LoginRequiredMixin, CreateView):
"""
model = ScheduleAssignment
form_class = ScheduleAssignmentForm
- template_name = 'hr/schedule_assignment_form.html'
+ template_name = 'hr/assignments/schedule_assignment_form.html'
success_url = reverse_lazy('hr:schedule_assignment_list')
def form_valid(self, form):
@@ -540,7 +520,7 @@ class ScheduleAssignmentUpdateView(LoginRequiredMixin, UpdateView):
"""
model = ScheduleAssignment
form_class = ScheduleAssignmentForm
- template_name = 'hr/schedule_assignment_form.html'
+ template_name = 'hr/assignments/schedule_assignment_form.html'
success_url = reverse_lazy('hr:schedule_assignment_list')
def get_queryset(self):
@@ -556,16 +536,12 @@ class ScheduleAssignmentUpdateView(LoginRequiredMixin, UpdateView):
return kwargs
-# ============================================================================
-# TIME ENTRY VIEWS (RESTRICTED CRUD - Operational Data)
-# ============================================================================
-
class TimeEntryListView(LoginRequiredMixin, ListView):
"""
List time entries with filtering capabilities.
"""
model = TimeEntry
- template_name = 'hr/time_entry_list.html'
+ template_name = 'hr/time_entries/time_entry_list.html'
context_object_name = 'time_entries'
paginate_by = 20
@@ -600,7 +576,7 @@ class TimeEntryDetailView(LoginRequiredMixin, DetailView):
Display detailed information about a specific time entry.
"""
model = TimeEntry
- template_name = 'hr/time_entry_detail.html'
+ template_name = 'hr/time_entries/time_entry_detail.html'
context_object_name = 'time_entry'
def get_queryset(self):
@@ -613,7 +589,7 @@ class TimeEntryCreateView(LoginRequiredMixin, CreateView):
"""
model = TimeEntry
form_class = TimeEntryForm
- template_name = 'hr/time_entry_form.html'
+ template_name = 'hr/time_entries/time_entry_form.html'
success_url = reverse_lazy('hr:time_entry_list')
def form_valid(self, form):
@@ -632,7 +608,7 @@ class TimeEntryUpdateView(LoginRequiredMixin, UpdateView):
"""
model = TimeEntry
form_class = TimeEntryForm
- template_name = 'hr/time_entry_form.html'
+ template_name = 'hr/time_entries/time_entry_form.html'
success_url = reverse_lazy('hr:time_entry_list')
def get_queryset(self):
@@ -653,16 +629,12 @@ class TimeEntryUpdateView(LoginRequiredMixin, UpdateView):
return kwargs
-# ============================================================================
-# PERFORMANCE REVIEW VIEWS (FULL CRUD - Operational Data)
-# ============================================================================
-
class PerformanceReviewListView(LoginRequiredMixin, ListView):
"""
List performance reviews with filtering capabilities.
"""
model = PerformanceReview
- template_name = 'hr/performance_review_list.html'
+ template_name = 'hr/reviews/performance_review_list.html'
context_object_name = 'reviews'
paginate_by = 20
@@ -694,11 +666,80 @@ class PerformanceReviewDetailView(LoginRequiredMixin, DetailView):
Display detailed information about a specific performance review.
"""
model = PerformanceReview
- template_name = 'hr/performance_review_detail.html'
+ template_name = 'hr/reviews/performance_review_detail.html'
context_object_name = 'review'
-
+
def get_queryset(self):
- return PerformanceReview.objects.filter(employee__tenant=self.request.user.tenant)
+ # Eager load employee + department + supervisor to reduce queries
+ return (PerformanceReview.objects
+ .select_related('employee', 'employee__department', 'employee__supervisor', 'reviewer')
+ .filter(employee__tenant=self.request.user.tenant))
+
+ def get_object(self, queryset=None):
+ queryset = queryset or self.get_queryset()
+ return get_object_or_404(queryset, pk=self.kwargs.get('pk') or self.kwargs.get('id'))
+
+ @staticmethod
+ def _split_lines(text):
+ if not text:
+ return []
+ parts = []
+ for line in str(text).replace('\r', '').split('\n'):
+ for piece in line.split(';'):
+ piece = piece.strip()
+ if piece:
+ parts.append(piece)
+ return parts
+
+ def get_context_data(self, **kwargs):
+ ctx = super().get_context_data(**kwargs)
+ review = ctx['review']
+
+ # Build categories from competency_ratings JSON: { "Teamwork": 4.0, ... }
+ # Make a list of dicts the template can iterate through.
+ categories = []
+ ratings = review.competency_ratings or {}
+ # Keep a stable order (by key) to avoid chart jitter
+ for name in sorted(ratings.keys()):
+ try:
+ score = float(ratings[name])
+ except (TypeError, ValueError):
+ score = 0.0
+ categories.append({'name': name, 'score': score, 'comments': ''})
+
+ # Previous reviews (same employee, exclude current)
+ previous_reviews = (
+ PerformanceReview.objects
+ .filter(employee=review.employee)
+ .exclude(pk=review.pk)
+ .order_by('-review_date')[:5]
+ .select_related('employee')
+ )
+
+ # Strengths / AFI lists for bullet rendering
+ strengths_list = self._split_lines(review.strengths)
+ afi_list = self._split_lines(review.areas_for_improvement)
+
+ # Goals blocks as lists for nicer display
+ goals_achieved_list = self._split_lines(review.goals_achieved)
+ goals_not_achieved_list = self._split_lines(review.goals_not_achieved)
+ future_goals_list = self._split_lines(review.future_goals)
+
+ ctx.update({
+ 'categories': categories,
+ 'previous_reviews': previous_reviews,
+ 'review_strengths_list': strengths_list,
+ 'review_afi_list': afi_list,
+ 'goals_achieved_list': goals_achieved_list,
+ 'goals_not_achieved_list': goals_not_achieved_list,
+ 'future_goals_list': future_goals_list,
+ })
+
+ # convenience on the review object (template already expects these list props sometimes)
+ setattr(review, 'strengths_list', strengths_list)
+ setattr(review, 'areas_for_improvement_list', afi_list)
+
+ return ctx
class PerformanceReviewCreateView(LoginRequiredMixin, CreateView):
@@ -707,7 +748,7 @@ class PerformanceReviewCreateView(LoginRequiredMixin, CreateView):
"""
model = PerformanceReview
form_class = PerformanceReviewForm
- template_name = 'hr/performance_review_form.html'
+ template_name = 'hr/reviews/performance_review_form.html'
success_url = reverse_lazy('hr:performance_review_list')
def form_valid(self, form):
@@ -727,7 +768,7 @@ class PerformanceReviewUpdateView(LoginRequiredMixin, UpdateView):
"""
model = PerformanceReview
form_class = PerformanceReviewForm
- template_name = 'hr/performance_review_form.html'
+ template_name = 'hr/reviews/performance_review_form.html'
def get_queryset(self):
return PerformanceReview.objects.filter(employee__tenant=self.request.user.tenant)
@@ -750,7 +791,7 @@ class PerformanceReviewDeleteView(LoginRequiredMixin, DeleteView):
Delete a performance review (only if not finalized).
"""
model = PerformanceReview
- template_name = 'hr/performance_review_confirm_delete.html'
+ template_name = 'hr/reviews/performance_review_confirm_delete.html'
success_url = reverse_lazy('hr:performance_review_list')
def get_queryset(self):
@@ -768,39 +809,128 @@ class PerformanceReviewDeleteView(LoginRequiredMixin, DeleteView):
return super().delete(request, *args, **kwargs)
-# ============================================================================
-# TRAINING RECORD VIEWS (FULL CRUD - Operational Data)
-# ============================================================================
+class TrainingManagementView(LoginRequiredMixin, ListView):
+ model = TrainingRecord
+ template_name = 'hr/training/training_management.html'
+ context_object_name = 'training_records'
+ paginate_by = 20
+
+ def get_queryset(self):
+ qs = (TrainingRecord.objects
+ .filter(employee__tenant=self.request.user.tenant)
+ .select_related('employee', 'employee__department')
+ .order_by('-training_date', '-completion_date'))
+ # optional GET filters (works with the template’s inputs)
+ if emp := self.request.GET.get('employee'):
+ qs = qs.filter(employee_id=emp)
+ if ttype := self.request.GET.get('training_type'):
+ qs = qs.filter(training_type=ttype)
+ if status := self.request.GET.get('status'):
+ qs = qs.filter(status=status)
+ return qs
+
+ def get_context_data(self, **kwargs):
+ ctx = super().get_context_data(**kwargs)
+ tenant = self.request.user.tenant
+ today = timezone.now().date()
+
+ base = TrainingRecord.objects.filter(employee__tenant=tenant)
+
+ total_records = base.count()
+ completed_trainings = base.filter(status='COMPLETED').count()
+ pending_trainings = base.filter(status__in=['SCHEDULED', 'IN_PROGRESS']).count()
+ overdue_trainings = base.filter(expiry_date__lt=today, expiry_date__isnull=False).exclude(
+ status='COMPLETED').count()
+
+ # compliance rate = “not expired” among trainings that have an expiry_date
+ with_expiry = base.filter(expiry_date__isnull=False)
+ valid_now = with_expiry.filter(expiry_date__gte=today).count()
+ compliance_rate = round((valid_now / with_expiry.count()) * 100, 1) if with_expiry.exists() else 100.0
+
+ # expiring soon = within 30 days
+ expiring_soon_count = with_expiry.filter(expiry_date__gte=today,
+ expiry_date__lte=today + timedelta(days=30)).count()
+
+ # department compliance (simple example: percent of non-expired per dept among those with expiry)
+ dept_rows = []
+ departments = Department.objects.filter(tenant=tenant).order_by('name')
+ for d in departments:
+ d_qs = with_expiry.filter(employee__department=d)
+ if not d_qs.exists():
+ rate = 100
+ else:
+ ok = d_qs.filter(expiry_date__gte=today).count()
+ rate = round((ok / d_qs.count()) * 100)
+ color = 'success' if rate >= 90 else 'warning' if rate >= 70 else 'danger'
+ dept_rows.append({'name': d.name, 'compliance_rate': rate, 'compliance_color': color})
+
+ # “compliance alerts” demo (overdue/expiring soon)
+ alerts = []
+ for tr in base.select_related('employee'):
+ if tr.expiry_date:
+ if tr.expiry_date < today:
+ alerts.append({
+ 'id': tr.id,
+ 'employee': tr.employee,
+ 'requirement': tr.training_name,
+ 'due_date': tr.expiry_date,
+ 'priority_color': 'danger',
+ 'urgency_color': 'danger',
+ 'get_priority_display': 'Overdue',
+ })
+ elif today <= tr.expiry_date <= today + timedelta(days=30):
+ alerts.append({
+ 'id': tr.id,
+ 'employee': tr.employee,
+ 'requirement': tr.training_name,
+ 'due_date': tr.expiry_date,
+ 'priority_color': 'warning',
+ 'urgency_color': 'warning',
+ 'get_priority_display': 'Expiring Soon',
+ })
+
+ ctx.update({
+ 'total_records': total_records,
+ 'completed_trainings': completed_trainings,
+ 'pending_trainings': pending_trainings,
+ 'overdue_trainings': overdue_trainings,
+ 'departments': departments,
+ 'compliance_rate': compliance_rate,
+ 'expiring_soon_count': expiring_soon_count,
+ 'department_compliance': dept_rows,
+ 'compliance_alerts': alerts,
+ })
+ return ctx
class TrainingRecordListView(LoginRequiredMixin, ListView):
"""
- List training records with filtering capabilities.
- """
+ List training records with filtering capabilities.
+ """
model = TrainingRecord
- template_name = 'hr/training_record_list.html'
+ template_name = 'hr/training/training_record_list.html'
context_object_name = 'training_records'
paginate_by = 20
-
+
def get_queryset(self):
queryset = TrainingRecord.objects.filter(
employee__tenant=self.request.user.tenant
).select_related('employee')
-
+
# Filter by employee
employee = self.request.GET.get('employee')
if employee:
queryset = queryset.filter(employee_id=employee)
-
+
# Filter by training type
training_type = self.request.GET.get('training_type')
if training_type:
queryset = queryset.filter(training_type=training_type)
-
+
# Filter by completion status
status = self.request.GET.get('status')
if status:
queryset = queryset.filter(status=status)
-
+
return queryset.order_by('-completion_date')
@@ -809,8 +939,8 @@ class TrainingRecordDetailView(LoginRequiredMixin, DetailView):
Display detailed information about a specific training record.
"""
model = TrainingRecord
- template_name = 'hr/training_record_detail.html'
- context_object_name = 'training_record'
+ template_name = 'hr/training/training_record_detail.html'
+ context_object_name = 'record'
def get_queryset(self):
return TrainingRecord.objects.filter(employee__tenant=self.request.user.tenant)
@@ -822,7 +952,7 @@ class TrainingRecordCreateView(LoginRequiredMixin, CreateView):
"""
model = TrainingRecord
form_class = TrainingRecordForm
- template_name = 'hr/training_record_form.html'
+ template_name = 'hr/training/training_record_form.html'
success_url = reverse_lazy('hr:training_record_list')
def form_valid(self, form):
@@ -842,7 +972,7 @@ class TrainingRecordUpdateView(LoginRequiredMixin, UpdateView):
"""
model = TrainingRecord
form_class = TrainingRecordForm
- template_name = 'hr/training_record_form.html'
+ template_name = 'hr/training/training_record_form.html'
def get_queryset(self):
return TrainingRecord.objects.filter(employee__tenant=self.request.user.tenant)
@@ -865,7 +995,7 @@ class TrainingRecordDeleteView(LoginRequiredMixin, DeleteView):
Delete a training record.
"""
model = TrainingRecord
- template_name = 'hr/training_record_confirm_delete.html'
+ template_name = 'hr/training/training_record_confirm_delete.html'
success_url = reverse_lazy('hr:training_record_list')
def get_queryset(self):
@@ -876,9 +1006,15 @@ class TrainingRecordDeleteView(LoginRequiredMixin, DeleteView):
return super().delete(request, *args, **kwargs)
-# ============================================================================
-# HTMX VIEWS FOR REAL-TIME UPDATES
-# ============================================================================
+@login_required
+def complete_performance_review(request, review_id):
+ review = get_object_or_404(PerformanceReview, pk=review_id)
+ review.status = 'COMPLETED'
+ review.completed_by = request.user
+ review.save()
+
+ messages.success(request, 'Performance review completed successfully.')
+ return redirect('hr:performance_review_detail', pk=review.pk)
@login_required
def hr_stats(request):
@@ -961,10 +1097,6 @@ def attendance_summary(request):
return render(request, 'hr/partials/attendance_summary.html', context)
-# ============================================================================
-# ACTION VIEWS FOR WORKFLOW OPERATIONS
-# ============================================================================
-
@login_required
def clock_in(request):
"""
@@ -1093,7 +1225,7 @@ def approve_time_entry(request, entry_id):
next_url = request.POST.get('next', reverse('hr:time_entry_detail', kwargs={'pk': time_entry.id}))
return redirect(next_url)
- return render(request, 'hr/time_entry_approve.html', {
+ return render(request, 'hr/time_entries/time_entry_approve.html', {
'time_entry': time_entry
})
@@ -1123,15 +1255,11 @@ def publish_schedule(request, schedule_id):
messages.success(request, 'Schedule published successfully.')
return redirect('hr:schedule_detail', pk=schedule.id)
- return render(request, 'hr/schedule_publish.html', {
+ return render(request, 'hr/schedules/schedule_publish.html', {
'schedule': schedule
})
-# ============================================================================
-# API ENDPOINTS
-# ============================================================================
-
@login_required
def api_employee_list(request):
"""
@@ -1155,6 +1283,40 @@ def api_department_list(request):
return JsonResponse({'departments': list(departments)})
+
+# Query patterns to use if needed
+# # All upcoming sessions for a tenant (next 30 days)
+# TrainingSession.objects.filter(
+# tenant=request.user.tenant, start_at__gte=timezone.now(),
+# start_at__lte=timezone.now() + timedelta(days=30)
+# ).select_related('program', 'instructor')
+#
+# # Employees due for renewal in 30 days
+# TrainingCertificates.objects.filter(
+# tenant=request.user.tenant,
+# expiry_date__lte=date.today() + timedelta(days=30),
+# expiry_date__gte=date.today()
+# ).select_related('employee', 'program')
+#
+# # Enroll an employee, respecting capacity
+# session = TrainingSession.objects.select_for_update().get(pk=session_pk, tenant=tenant)
+# if session.capacity and session.enrollments.count() >= session.capacity:
+# status = 'WAITLISTED'
+# else:
+# status = 'SCHEDULED'
+# enrollment = TrainingRecord.objects.create(
+# tenant=tenant, employee=emp, program=session.program, session=session,
+# status=status, created_by=request.user
+# )
+#
+# # Mark completion + pass (auto-certificate will fire via signal)
+# enrollment.status = 'COMPLETED'
+# enrollment.passed = True
+# enrollment.completion_date = date.today()
+# enrollment.credits_earned = enrollment.hours
+# enrollment.save()
+
+
#
# from django.shortcuts import render, redirect, get_object_or_404
# from django.views.generic import (
diff --git a/inpatients/__pycache__/flows.cpython-312.pyc b/inpatients/__pycache__/flows.cpython-312.pyc
new file mode 100644
index 00000000..6cd8ebb6
Binary files /dev/null and b/inpatients/__pycache__/flows.cpython-312.pyc differ
diff --git a/inpatients/flows.py b/inpatients/flows.py
new file mode 100644
index 00000000..0d7ed355
--- /dev/null
+++ b/inpatients/flows.py
@@ -0,0 +1,757 @@
+# """
+# Viewflow workflows for inpatients app.
+# Provides admission, transfer, and discharge workflows.
+# """
+#
+# from viewflow import Flow, lock
+# from viewflow.base import this, flow_func
+# from viewflow.contrib import celery
+# from viewflow.decorators import flow_view
+# from viewflow.fields import CharField, ModelField
+# from viewflow.forms import ModelForm
+# from viewflow.views import CreateProcessView, UpdateProcessView
+# from viewflow.models import Process, Task
+# from django.contrib.auth.models import User
+# from django.urls import reverse_lazy
+# from django.utils import timezone
+# from django.db import transaction
+# from django.core.mail import send_mail
+#
+# from .models import Admission, Transfer, DischargeSummary, Ward, Bed
+# from .views import (
+# AdmissionRegistrationView, BedAssignmentView, MedicalAssessmentView,
+# NursingAssessmentView, AdmissionOrdersView, TransferRequestView,
+# TransferApprovalView, TransferExecutionView, DischargeInitiationView,
+# DischargePlanningView, DischargeExecutionView
+# )
+#
+#
+# class AdmissionProcess(Process):
+# """
+# Viewflow process model for patient admissions
+# """
+# admission = ModelField(Admission, help_text='Associated admission record')
+#
+# # Process status tracking
+# registration_completed = models.BooleanField(default=False)
+# bed_assigned = models.BooleanField(default=False)
+# medical_assessment_completed = models.BooleanField(default=False)
+# nursing_assessment_completed = models.BooleanField(default=False)
+# orders_written = models.BooleanField(default=False)
+# admission_completed = models.BooleanField(default=False)
+#
+# class Meta:
+# verbose_name = 'Admission Process'
+# verbose_name_plural = 'Admission Processes'
+#
+#
+# class AdmissionFlow(Flow):
+# """
+# Hospital Patient Admission Workflow
+#
+# This flow manages the complete patient admission process from
+# initial registration through final admission completion.
+# """
+#
+# process_class = AdmissionProcess
+#
+# # Flow definition
+# start = (
+# flow_func(this.start_admission)
+# .Next(this.patient_registration)
+# )
+#
+# patient_registration = (
+# flow_view(AdmissionRegistrationView)
+# .Permission('inpatients.can_register_admissions')
+# .Next(this.check_bed_availability)
+# )
+#
+# check_bed_availability = (
+# flow_func(this.check_beds)
+# .Next(this.bed_assignment)
+# )
+#
+# bed_assignment = (
+# flow_view(BedAssignmentView)
+# .Permission('inpatients.can_assign_beds')
+# .Next(this.parallel_assessments)
+# )
+#
+# parallel_assessments = (
+# flow_func(this.start_parallel_assessments)
+# .Next(this.medical_assessment)
+# .Next(this.nursing_assessment)
+# )
+#
+# medical_assessment = (
+# flow_view(MedicalAssessmentView)
+# .Permission('inpatients.can_perform_medical_assessment')
+# .Next(this.join_assessments)
+# )
+#
+# nursing_assessment = (
+# flow_view(NursingAssessmentView)
+# .Permission('inpatients.can_perform_nursing_assessment')
+# .Next(this.join_assessments)
+# )
+#
+# join_assessments = (
+# flow_func(this.join_parallel_assessments)
+# .Next(this.write_admission_orders)
+# )
+#
+# write_admission_orders = (
+# flow_view(AdmissionOrdersView)
+# .Permission('inpatients.can_write_orders')
+# .Next(this.finalize_admission)
+# )
+#
+# finalize_admission = (
+# flow_func(this.complete_admission)
+# .Next(this.end)
+# )
+#
+# end = flow_func(this.end_admission)
+#
+# # Flow functions
+# def start_admission(self, activation):
+# """Initialize the admission process"""
+# process = activation.process
+# admission = process.admission
+#
+# # Update admission status
+# admission.status = 'PENDING'
+# admission.save()
+#
+# # Send notification to registration staff
+# self.notify_registration_staff(admission)
+#
+# def check_beds(self, activation):
+# """Check bed availability for the patient"""
+# process = activation.process
+# admission = process.admission
+#
+# # Check if beds are available in the requested ward
+# available_beds = Bed.objects.filter(
+# ward=admission.current_ward,
+# status='AVAILABLE'
+# ).count()
+#
+# if available_beds == 0:
+# # Handle no beds available - could trigger waiting list
+# admission.admission_notes += f"\nNo beds available in {admission.current_ward.name} at {timezone.now()}"
+# admission.save()
+#
+# # Notify bed management
+# self.notify_bed_shortage(admission)
+#
+# def start_parallel_assessments(self, activation):
+# """Start parallel medical and nursing assessments"""
+# process = activation.process
+#
+# # Create assessment tasks
+# self.create_assessment_tasks(process)
+#
+# def join_parallel_assessments(self, activation):
+# """Wait for both assessments to complete"""
+# process = activation.process
+#
+# # Check if both assessments are completed
+# if (process.medical_assessment_completed and
+# process.nursing_assessment_completed):
+#
+# # Notify physician to write orders
+# self.notify_physician_for_orders(process.admission)
+#
+# def complete_admission(self, activation):
+# """Finalize the admission process"""
+# process = activation.process
+# admission = process.admission
+#
+# # Update admission status
+# admission.status = 'ADMITTED'
+# admission.save()
+#
+# # Update bed status
+# if admission.current_bed:
+# admission.current_bed.status = 'OCCUPIED'
+# admission.current_bed.current_patient = admission.patient
+# admission.current_bed.current_admission = admission
+# admission.current_bed.occupied_since = timezone.now()
+# admission.current_bed.save()
+#
+# # Mark process as completed
+# process.admission_completed = True
+# process.save()
+#
+# # Send completion notifications
+# self.notify_admission_complete(admission)
+#
+# def end_admission(self, activation):
+# """End the admission workflow"""
+# process = activation.process
+#
+# # Generate admission summary report
+# self.generate_admission_summary(process.admission)
+#
+# # Helper methods
+# def notify_registration_staff(self, admission):
+# """Notify registration staff of new admission"""
+# from django.contrib.auth.models import Group
+#
+# registration_staff = User.objects.filter(
+# groups__name='Registration Staff'
+# )
+#
+# for staff in registration_staff:
+# send_mail(
+# subject=f'New Admission: {admission.patient.get_full_name()}',
+# message=f'A new {admission.get_admission_type_display()} admission has been initiated.',
+# from_email='admissions@hospital.com',
+# recipient_list=[staff.email],
+# fail_silently=True
+# )
+#
+# def notify_bed_shortage(self, admission):
+# """Notify bed management of shortage"""
+# from django.contrib.auth.models import Group
+#
+# bed_managers = User.objects.filter(
+# groups__name='Bed Management'
+# )
+#
+# for manager in bed_managers:
+# send_mail(
+# subject=f'Bed Shortage Alert - {admission.current_ward.name}',
+# message=f'No beds available for admission of {admission.patient.get_full_name()}.',
+# from_email='admissions@hospital.com',
+# recipient_list=[manager.email],
+# fail_silently=True
+# )
+#
+# def create_assessment_tasks(self, process):
+# """Create assessment tasks for medical and nursing staff"""
+# # This would create tasks in a task management system
+# pass
+#
+# def notify_physician_for_orders(self, admission):
+# """Notify attending physician to write orders"""
+# if admission.attending_physician and admission.attending_physician.email:
+# send_mail(
+# subject=f'Admission Orders Required: {admission.patient.get_full_name()}',
+# message=f'Please write admission orders. Both assessments are complete.',
+# from_email='admissions@hospital.com',
+# recipient_list=[admission.attending_physician.email],
+# fail_silently=True
+# )
+#
+# def notify_admission_complete(self, admission):
+# """Notify relevant staff that admission is complete"""
+# # Notify nursing staff
+# nursing_staff = User.objects.filter(
+# groups__name='Nursing Staff',
+# profile__department=admission.current_ward
+# )
+#
+# for nurse in nursing_staff:
+# send_mail(
+# subject=f'New Patient Admitted: {admission.patient.get_full_name()}',
+# message=f'Patient has been admitted to {admission.current_bed.room_number if admission.current_bed else "TBD"}.',
+# from_email='admissions@hospital.com',
+# recipient_list=[nurse.email],
+# fail_silently=True
+# )
+#
+# def generate_admission_summary(self, admission):
+# """Generate admission summary report"""
+# # This would generate a comprehensive admission report
+# pass
+#
+#
+# class TransferProcess(Process):
+# """
+# Viewflow process model for patient transfers
+# """
+# transfer = ModelField(Transfer, help_text='Associated transfer record')
+#
+# # Process status tracking
+# request_approved = models.BooleanField(default=False)
+# bed_prepared = models.BooleanField(default=False)
+# transport_arranged = models.BooleanField(default=False)
+# handoff_completed = models.BooleanField(default=False)
+# transfer_completed = models.BooleanField(default=False)
+#
+# class Meta:
+# verbose_name = 'Transfer Process'
+# verbose_name_plural = 'Transfer Processes'
+#
+#
+# class TransferFlow(Flow):
+# """
+# Hospital Patient Transfer Workflow
+#
+# This flow manages patient transfers between wards, beds, or units.
+# """
+#
+# process_class = TransferProcess
+#
+# # Flow definition
+# start = (
+# flow_func(this.start_transfer)
+# .Next(this.transfer_request)
+# )
+#
+# transfer_request = (
+# flow_view(TransferRequestView)
+# .Permission('inpatients.can_request_transfers')
+# .Next(this.transfer_approval)
+# )
+#
+# transfer_approval = (
+# flow_view(TransferApprovalView)
+# .Permission('inpatients.can_approve_transfers')
+# .Next(this.prepare_destination)
+# )
+#
+# prepare_destination = (
+# flow_func(this.prepare_bed)
+# .Next(this.arrange_transport)
+# )
+#
+# arrange_transport = (
+# flow_func(this.schedule_transport)
+# .Next(this.execute_transfer)
+# )
+#
+# execute_transfer = (
+# flow_view(TransferExecutionView)
+# .Permission('inpatients.can_execute_transfers')
+# .Next(this.complete_transfer)
+# )
+#
+# complete_transfer = (
+# flow_func(this.finalize_transfer)
+# .Next(this.end)
+# )
+#
+# end = flow_func(this.end_transfer)
+#
+# # Flow functions
+# def start_transfer(self, activation):
+# """Initialize the transfer process"""
+# process = activation.process
+# transfer = process.transfer
+#
+# # Update transfer status
+# transfer.status = 'REQUESTED'
+# transfer.save()
+#
+# # Notify receiving ward
+# self.notify_receiving_ward(transfer)
+#
+# def prepare_bed(self, activation):
+# """Prepare destination bed"""
+# process = activation.process
+# transfer = process.transfer
+#
+# if transfer.to_bed:
+# # Reserve the destination bed
+# transfer.to_bed.status = 'RESERVED'
+# transfer.to_bed.reserved_until = timezone.now() + timezone.timedelta(hours=2)
+# transfer.to_bed.save()
+#
+# process.bed_prepared = True
+# process.save()
+#
+# def schedule_transport(self, activation):
+# """Schedule patient transport"""
+# process = activation.process
+# transfer = process.transfer
+#
+# # Auto-schedule transport based on priority
+# if transfer.priority in ['EMERGENT', 'STAT']:
+# transfer.scheduled_datetime = timezone.now() + timezone.timedelta(minutes=15)
+# elif transfer.priority == 'URGENT':
+# transfer.scheduled_datetime = timezone.now() + timezone.timedelta(hours=1)
+# else:
+# transfer.scheduled_datetime = timezone.now() + timezone.timedelta(hours=4)
+#
+# transfer.save()
+#
+# process.transport_arranged = True
+# process.save()
+#
+# # Notify transport team
+# self.notify_transport_team(transfer)
+#
+# def finalize_transfer(self, activation):
+# """Finalize the transfer process"""
+# process = activation.process
+# transfer = process.transfer
+# admission = transfer.admission
+#
+# # Update admission location
+# admission.current_ward = transfer.to_ward
+# admission.current_bed = transfer.to_bed
+# admission.save()
+#
+# # Update bed statuses
+# if transfer.from_bed:
+# transfer.from_bed.status = 'AVAILABLE'
+# transfer.from_bed.current_patient = None
+# transfer.from_bed.current_admission = None
+# transfer.from_bed.occupied_since = None
+# transfer.from_bed.save()
+#
+# if transfer.to_bed:
+# transfer.to_bed.status = 'OCCUPIED'
+# transfer.to_bed.current_patient = transfer.patient
+# transfer.to_bed.current_admission = admission
+# transfer.to_bed.occupied_since = timezone.now()
+# transfer.to_bed.save()
+#
+# # Update transfer status
+# transfer.status = 'COMPLETED'
+# transfer.actual_datetime = timezone.now()
+# transfer.save()
+#
+# process.transfer_completed = True
+# process.save()
+#
+# # Send completion notifications
+# self.notify_transfer_complete(transfer)
+#
+# def end_transfer(self, activation):
+# """End the transfer workflow"""
+# process = activation.process
+#
+# # Generate transfer summary
+# self.generate_transfer_summary(process.transfer)
+#
+# # Helper methods
+# def notify_receiving_ward(self, transfer):
+# """Notify receiving ward of incoming transfer"""
+# receiving_staff = User.objects.filter(
+# groups__name='Nursing Staff',
+# profile__department=transfer.to_ward
+# )
+#
+# for staff in receiving_staff:
+# send_mail(
+# subject=f'Incoming Transfer: {transfer.patient.get_full_name()}',
+# message=f'Patient transfer requested from {transfer.from_ward.name}.',
+# from_email='transfers@hospital.com',
+# recipient_list=[staff.email],
+# fail_silently=True
+# )
+#
+# def notify_transport_team(self, transfer):
+# """Notify transport team of scheduled transfer"""
+# transport_staff = User.objects.filter(
+# groups__name='Transport Team'
+# )
+#
+# for staff in transport_staff:
+# send_mail(
+# subject=f'Transport Scheduled: {transfer.patient.get_full_name()}',
+# message=f'Transfer scheduled for {transfer.scheduled_datetime}.',
+# from_email='transport@hospital.com',
+# recipient_list=[staff.email],
+# fail_silently=True
+# )
+#
+# def notify_transfer_complete(self, transfer):
+# """Notify relevant staff that transfer is complete"""
+# # Notify both sending and receiving wards
+# all_staff = User.objects.filter(
+# groups__name='Nursing Staff',
+# profile__department__in=[transfer.from_ward, transfer.to_ward]
+# )
+#
+# for staff in all_staff:
+# send_mail(
+# subject=f'Transfer Complete: {transfer.patient.get_full_name()}',
+# message=f'Patient transfer from {transfer.from_ward.name} to {transfer.to_ward.name} completed.',
+# from_email='transfers@hospital.com',
+# recipient_list=[staff.email],
+# fail_silently=True
+# )
+#
+# def generate_transfer_summary(self, transfer):
+# """Generate transfer summary report"""
+# # This would generate a comprehensive transfer report
+# pass
+#
+#
+# class DischargeProcess(Process):
+# """
+# Viewflow process model for patient discharges
+# """
+# admission = ModelField(Admission, help_text='Associated admission record')
+# discharge_summary = ModelField(DischargeSummary, null=True, blank=True,
+# help_text='Associated discharge summary')
+#
+# # Process status tracking
+# discharge_planning_started = models.BooleanField(default=False)
+# discharge_orders_written = models.BooleanField(default=False)
+# discharge_summary_completed = models.BooleanField(default=False)
+# patient_education_completed = models.BooleanField(default=False)
+# medications_reconciled = models.BooleanField(default=False)
+# follow_up_scheduled = models.BooleanField(default=False)
+# discharge_completed = models.BooleanField(default=False)
+#
+# class Meta:
+# verbose_name = 'Discharge Process'
+# verbose_name_plural = 'Discharge Processes'
+#
+#
+# class DischargeFlow(Flow):
+# """
+# Hospital Patient Discharge Workflow
+#
+# This flow manages the complete patient discharge process from
+# discharge planning through final discharge completion.
+# """
+#
+# process_class = DischargeProcess
+#
+# # Flow definition
+# start = (
+# flow_func(this.start_discharge)
+# .Next(this.discharge_planning)
+# )
+#
+# discharge_planning = (
+# flow_view(DischargePlanningView)
+# .Permission('inpatients.can_plan_discharges')
+# .Next(this.write_discharge_orders)
+# )
+#
+# write_discharge_orders = (
+# flow_view(DischargeOrdersView)
+# .Permission('inpatients.can_write_discharge_orders')
+# .Next(this.parallel_discharge_tasks)
+# )
+#
+# parallel_discharge_tasks = (
+# flow_func(this.start_parallel_discharge_tasks)
+# .Next(this.complete_discharge_summary)
+# .Next(this.patient_education)
+# .Next(this.medication_reconciliation)
+# .Next(this.schedule_follow_up)
+# )
+#
+# complete_discharge_summary = (
+# flow_view(DischargeDocumentationView)
+# .Permission('inpatients.can_complete_discharge_summary')
+# .Next(this.join_discharge_tasks)
+# )
+#
+# patient_education = (
+# flow_view(PatientEducationView)
+# .Permission('inpatients.can_provide_patient_education')
+# .Next(this.join_discharge_tasks)
+# )
+#
+# medication_reconciliation = (
+# flow_view(MedicationReconciliationView)
+# .Permission('inpatients.can_reconcile_medications')
+# .Next(this.join_discharge_tasks)
+# )
+#
+# schedule_follow_up = (
+# flow_view(FollowUpSchedulingView)
+# .Permission('inpatients.can_schedule_follow_up')
+# .Next(this.join_discharge_tasks)
+# )
+#
+# join_discharge_tasks = (
+# flow_func(this.join_parallel_discharge_tasks)
+# .Next(this.execute_discharge)
+# )
+#
+# execute_discharge = (
+# flow_view(DischargeExecutionView)
+# .Permission('inpatients.can_execute_discharges')
+# .Next(this.finalize_discharge)
+# )
+#
+# finalize_discharge = (
+# flow_func(this.complete_discharge)
+# .Next(this.end)
+# )
+#
+# end = flow_func(this.end_discharge)
+#
+# # Flow functions
+# def start_discharge(self, activation):
+# """Initialize the discharge process"""
+# process = activation.process
+# admission = process.admission
+#
+# # Update admission discharge planning status
+# admission.discharge_planning_started = True
+# admission.save()
+#
+# # Notify discharge planning team
+# self.notify_discharge_planning_team(admission)
+#
+# def start_parallel_discharge_tasks(self, activation):
+# """Start parallel discharge preparation tasks"""
+# process = activation.process
+#
+# # Create discharge preparation tasks
+# self.create_discharge_tasks(process)
+#
+# def join_parallel_discharge_tasks(self, activation):
+# """Wait for all discharge tasks to complete"""
+# process = activation.process
+#
+# # Check if all discharge tasks are completed
+# if (process.discharge_summary_completed and
+# process.patient_education_completed and
+# process.medications_reconciled and
+# process.follow_up_scheduled):
+#
+# # Notify that patient is ready for discharge
+# self.notify_ready_for_discharge(process.admission)
+#
+# def complete_discharge(self, activation):
+# """Finalize the discharge process"""
+# process = activation.process
+# admission = process.admission
+#
+# # Update admission status
+# admission.status = 'DISCHARGED'
+# admission.discharge_datetime = timezone.now()
+# admission.save()
+#
+# # Update bed status
+# if admission.current_bed:
+# admission.current_bed.status = 'CLEANING'
+# admission.current_bed.current_patient = None
+# admission.current_bed.current_admission = None
+# admission.current_bed.occupied_since = None
+# admission.current_bed.save()
+#
+# # Mark process as completed
+# process.discharge_completed = True
+# process.save()
+#
+# # Send completion notifications
+# self.notify_discharge_complete(admission)
+#
+# def end_discharge(self, activation):
+# """End the discharge workflow"""
+# process = activation.process
+#
+# # Generate discharge summary report
+# self.generate_final_discharge_report(process.admission)
+#
+# # Helper methods
+# def notify_discharge_planning_team(self, admission):
+# """Notify discharge planning team"""
+# discharge_planners = User.objects.filter(
+# groups__name='Discharge Planning'
+# )
+#
+# for planner in discharge_planners:
+# send_mail(
+# subject=f'Discharge Planning Required: {admission.patient.get_full_name()}',
+# message=f'Discharge planning has been initiated.',
+# from_email='discharge@hospital.com',
+# recipient_list=[planner.email],
+# fail_silently=True
+# )
+#
+# def create_discharge_tasks(self, process):
+# """Create discharge preparation tasks"""
+# # This would create tasks in a task management system
+# pass
+#
+# def notify_ready_for_discharge(self, admission):
+# """Notify that patient is ready for discharge"""
+# if admission.attending_physician and admission.attending_physician.email:
+# send_mail(
+# subject=f'Patient Ready for Discharge: {admission.patient.get_full_name()}',
+# message=f'All discharge preparations are complete.',
+# from_email='discharge@hospital.com',
+# recipient_list=[admission.attending_physician.email],
+# fail_silently=True
+# )
+#
+# def notify_discharge_complete(self, admission):
+# """Notify relevant staff that discharge is complete"""
+# # Notify nursing staff and housekeeping
+# relevant_staff = User.objects.filter(
+# groups__name__in=['Nursing Staff', 'Housekeeping'],
+# profile__department=admission.current_ward
+# )
+#
+# for staff in relevant_staff:
+# send_mail(
+# subject=f'Patient Discharged: {admission.patient.get_full_name()}',
+# message=f'Patient has been discharged from {admission.current_bed.room_number if admission.current_bed else "ward"}.',
+# from_email='discharge@hospital.com',
+# recipient_list=[staff.email],
+# fail_silently=True
+# )
+#
+# def generate_final_discharge_report(self, admission):
+# """Generate final discharge report"""
+# # This would generate a comprehensive discharge report
+# pass
+#
+#
+# # Celery tasks for background processing
+# @celery.job
+# def auto_assign_bed(admission_id, ward_id):
+# """Background task to automatically assign available bed"""
+# try:
+# admission = Admission.objects.get(id=admission_id)
+# ward = Ward.objects.get(id=ward_id)
+#
+# available_bed = Bed.objects.filter(
+# ward=ward,
+# status='AVAILABLE'
+# ).first()
+#
+# if available_bed:
+# admission.current_bed = available_bed
+# available_bed.status = 'RESERVED'
+# available_bed.save()
+# admission.save()
+# return True
+#
+# return False
+# except (Admission.DoesNotExist, Ward.DoesNotExist):
+# return False
+#
+#
+# @celery.job
+# def schedule_discharge_planning(admission_id, days_before_discharge=2):
+# """Background task to schedule discharge planning"""
+# try:
+# admission = Admission.objects.get(id=admission_id)
+#
+# if admission.estimated_length_of_stay:
+# planning_date = admission.admission_datetime + timezone.timedelta(
+# days=admission.estimated_length_of_stay - days_before_discharge
+# )
+#
+# # Schedule discharge planning
+# # This would integrate with a scheduling system
+# return True
+#
+# return False
+# except Admission.DoesNotExist:
+# return False
+#
+#
+# @celery.job
+# def generate_encounter_number():
+# """Generate unique encounter number"""
+# from django.utils.crypto import get_random_string
+# return f"ENC{timezone.now().strftime('%Y%m%d')}{get_random_string(4, '0123456789')}"
+#
diff --git a/integration/__pycache__/flows.cpython-312.pyc b/integration/__pycache__/flows.cpython-312.pyc
new file mode 100644
index 00000000..2b3c2434
Binary files /dev/null and b/integration/__pycache__/flows.cpython-312.pyc differ
diff --git a/integration/flows.py b/integration/flows.py
new file mode 100644
index 00000000..23834ca0
--- /dev/null
+++ b/integration/flows.py
@@ -0,0 +1,781 @@
+# """
+# Viewflow workflows for integration app.
+# Provides external system integration, data synchronization, and API management workflows.
+# """
+#
+# from viewflow import Flow, lock
+# from viewflow.base import this, flow_func
+# from viewflow.contrib import celery
+# from viewflow.decorators import flow_view
+# from viewflow.fields import CharField, ModelField
+# from viewflow.forms import ModelForm
+# from viewflow.views import CreateProcessView, UpdateProcessView
+# from viewflow.models import Process, Task
+# from django.contrib.auth.models import User
+# from django.urls import reverse_lazy
+# from django.utils import timezone
+# from django.db import transaction
+# from django.core.mail import send_mail
+#
+# from .models import (
+# ExternalSystem, IntegrationEndpoint, DataMapping, SyncConfiguration,
+# IntegrationExecution, WebhookEndpoint, WebhookExecution, IntegrationLog
+# )
+# from .views import (
+# SystemSetupView, EndpointConfigurationView, DataMappingView,
+# SyncConfigurationView, TestConnectionView, MonitoringView,
+# WebhookManagementView, SecurityConfigurationView, PerformanceOptimizationView
+# )
+#
+#
+# class SystemIntegrationProcess(Process):
+# """
+# Viewflow process model for system integration
+# """
+# external_system = ModelField(ExternalSystem, help_text='Associated external system')
+#
+# # Process status tracking
+# system_registered = models.BooleanField(default=False)
+# connection_tested = models.BooleanField(default=False)
+# endpoints_configured = models.BooleanField(default=False)
+# data_mapping_created = models.BooleanField(default=False)
+# security_configured = models.BooleanField(default=False)
+# testing_completed = models.BooleanField(default=False)
+# monitoring_setup = models.BooleanField(default=False)
+# integration_activated = models.BooleanField(default=False)
+#
+# class Meta:
+# verbose_name = 'System Integration Process'
+# verbose_name_plural = 'System Integration Processes'
+#
+#
+# class SystemIntegrationFlow(Flow):
+# """
+# System Integration Workflow
+#
+# This flow manages complete external system integration including
+# setup, configuration, testing, and activation.
+# """
+#
+# process_class = SystemIntegrationProcess
+#
+# # Flow definition
+# start = (
+# flow_func(this.start_system_integration)
+# .Next(this.register_system)
+# )
+#
+# register_system = (
+# flow_view(SystemSetupView)
+# .Permission('integration.can_setup_systems')
+# .Next(this.test_connection)
+# )
+#
+# test_connection = (
+# flow_view(TestConnectionView)
+# .Permission('integration.can_test_connections')
+# .Next(this.configure_endpoints)
+# )
+#
+# configure_endpoints = (
+# flow_view(EndpointConfigurationView)
+# .Permission('integration.can_configure_endpoints')
+# .Next(this.create_data_mapping)
+# )
+#
+# create_data_mapping = (
+# flow_view(DataMappingView)
+# .Permission('integration.can_create_mappings')
+# .Next(this.configure_security)
+# )
+#
+# configure_security = (
+# flow_view(SecurityConfigurationView)
+# .Permission('integration.can_configure_security')
+# .Next(this.complete_testing)
+# )
+#
+# complete_testing = (
+# flow_func(this.perform_integration_testing)
+# .Next(this.setup_monitoring)
+# )
+#
+# setup_monitoring = (
+# flow_view(MonitoringView)
+# .Permission('integration.can_setup_monitoring')
+# .Next(this.activate_integration)
+# )
+#
+# activate_integration = (
+# flow_func(this.activate_system_integration)
+# .Next(this.end)
+# )
+#
+# end = flow_func(this.end_system_integration)
+#
+# # Flow functions
+# def start_system_integration(self, activation):
+# """Initialize the system integration process"""
+# process = activation.process
+# system = process.external_system
+#
+# # Send integration notification
+# self.notify_integration_start(system)
+#
+# # Create integration checklist
+# self.create_integration_checklist(system)
+#
+# # Initialize integration logging
+# self.setup_integration_logging(system)
+#
+# def perform_integration_testing(self, activation):
+# """Perform comprehensive integration testing"""
+# process = activation.process
+# system = process.external_system
+#
+# # Execute integration tests
+# test_results = self.execute_integration_tests(system)
+#
+# # Mark testing completed
+# process.testing_completed = True
+# process.save()
+#
+# # Store test results
+# self.store_integration_test_results(system, test_results)
+#
+# # Validate test results
+# self.validate_test_results(system, test_results)
+#
+# def activate_system_integration(self, activation):
+# """Activate the system integration"""
+# process = activation.process
+# system = process.external_system
+#
+# # Activate system
+# system.is_active = True
+# system.save()
+#
+# # Mark integration activated
+# process.integration_activated = True
+# process.save()
+#
+# # Send activation notifications
+# self.notify_integration_activation(system)
+#
+# # Schedule health checks
+# self.schedule_health_checks(system)
+#
+# # Start monitoring
+# self.start_integration_monitoring(system)
+#
+# def end_system_integration(self, activation):
+# """End the system integration workflow"""
+# process = activation.process
+#
+# # Generate integration summary
+# self.generate_integration_summary(process.external_system)
+#
+# # Helper methods
+# def notify_integration_start(self, system):
+# """Notify integration start"""
+# integration_team = User.objects.filter(groups__name='Integration Team')
+# for staff in integration_team:
+# send_mail(
+# subject=f'System Integration Started: {system.name}',
+# message=f'Integration process started for "{system.name}".',
+# from_email='integration@hospital.com',
+# recipient_list=[staff.email],
+# fail_silently=True
+# )
+#
+# def create_integration_checklist(self, system):
+# """Create integration checklist"""
+# # This would create integration checklist
+# pass
+#
+# def setup_integration_logging(self, system):
+# """Setup integration logging"""
+# IntegrationLog.objects.create(
+# external_system=system,
+# level='info',
+# category='system',
+# message=f'Integration process started for {system.name}'
+# )
+#
+# def execute_integration_tests(self, system):
+# """Execute comprehensive integration tests"""
+# # This would run integration tests
+# return {'status': 'passed', 'tests_run': 10, 'failures': 0}
+#
+# def store_integration_test_results(self, system, results):
+# """Store integration test results"""
+# # This would store test results
+# pass
+#
+# def validate_test_results(self, system, results):
+# """Validate integration test results"""
+# # This would validate test results
+# if results.get('failures', 0) > 0:
+# raise Exception('Integration tests failed')
+#
+# def notify_integration_activation(self, system):
+# """Notify integration activation"""
+# # Notify relevant teams
+# integration_team = User.objects.filter(groups__name='Integration Team')
+# for staff in integration_team:
+# send_mail(
+# subject=f'System Integration Activated: {system.name}',
+# message=f'Integration for "{system.name}" has been activated.',
+# from_email='integration@hospital.com',
+# recipient_list=[staff.email],
+# fail_silently=True
+# )
+#
+# def schedule_health_checks(self, system):
+# """Schedule periodic health checks"""
+# # Schedule health check task
+# system_health_check.apply_async(
+# args=[system.system_id],
+# countdown=300 # 5 minutes
+# )
+#
+# def start_integration_monitoring(self, system):
+# """Start integration monitoring"""
+# # This would start monitoring
+# pass
+#
+# def generate_integration_summary(self, system):
+# """Generate integration summary"""
+# # This would generate integration summary
+# pass
+#
+#
+# class DataSynchronizationProcess(Process):
+# """
+# Viewflow process model for data synchronization
+# """
+# sync_configuration = ModelField(SyncConfiguration, help_text='Associated sync configuration')
+#
+# # Process status tracking
+# sync_initiated = models.BooleanField(default=False)
+# data_extracted = models.BooleanField(default=False)
+# data_transformed = models.BooleanField(default=False)
+# data_validated = models.BooleanField(default=False)
+# data_loaded = models.BooleanField(default=False)
+# conflicts_resolved = models.BooleanField(default=False)
+# sync_completed = models.BooleanField(default=False)
+#
+# class Meta:
+# verbose_name = 'Data Synchronization Process'
+# verbose_name_plural = 'Data Synchronization Processes'
+#
+#
+# class DataSynchronizationFlow(Flow):
+# """
+# Data Synchronization Workflow
+#
+# This flow manages automated data synchronization between
+# external systems and the hospital management system.
+# """
+#
+# process_class = DataSynchronizationProcess
+#
+# # Flow definition
+# start = (
+# flow_func(this.start_data_synchronization)
+# .Next(this.initiate_sync)
+# )
+#
+# initiate_sync = (
+# flow_func(this.setup_sync_process)
+# .Next(this.extract_data)
+# )
+#
+# extract_data = (
+# flow_func(this.perform_data_extraction)
+# .Next(this.transform_data)
+# )
+#
+# transform_data = (
+# flow_func(this.perform_data_transformation)
+# .Next(this.validate_data)
+# )
+#
+# validate_data = (
+# flow_func(this.perform_data_validation)
+# .Next(this.load_data)
+# )
+#
+# load_data = (
+# flow_func(this.perform_data_loading)
+# .Next(this.resolve_conflicts)
+# )
+#
+# resolve_conflicts = (
+# flow_func(this.handle_data_conflicts)
+# .Next(this.complete_sync)
+# )
+#
+# complete_sync = (
+# flow_func(this.finalize_data_synchronization)
+# .Next(this.end)
+# )
+#
+# end = flow_func(this.end_data_synchronization)
+#
+# # Flow functions
+# def start_data_synchronization(self, activation):
+# """Initialize the data synchronization process"""
+# process = activation.process
+# sync_config = process.sync_configuration
+#
+# # Send sync notification
+# self.notify_sync_start(sync_config)
+#
+# # Create sync execution record
+# self.create_sync_execution(sync_config)
+#
+# def setup_sync_process(self, activation):
+# """Setup synchronization process"""
+# process = activation.process
+# sync_config = process.sync_configuration
+#
+# # Mark sync initiated
+# process.sync_initiated = True
+# process.save()
+#
+# # Prepare sync environment
+# self.prepare_sync_environment(sync_config)
+#
+# def perform_data_extraction(self, activation):
+# """Extract data from source system"""
+# process = activation.process
+# sync_config = process.sync_configuration
+#
+# # Extract data
+# extracted_data = self.extract_source_data(sync_config)
+#
+# # Mark data extracted
+# process.data_extracted = True
+# process.save()
+#
+# # Store extracted data
+# self.store_extracted_data(sync_config, extracted_data)
+#
+# def perform_data_transformation(self, activation):
+# """Transform data according to mapping rules"""
+# process = activation.process
+# sync_config = process.sync_configuration
+#
+# # Transform data
+# transformed_data = self.transform_sync_data(sync_config)
+#
+# # Mark data transformed
+# process.data_transformed = True
+# process.save()
+#
+# # Store transformed data
+# self.store_transformed_data(sync_config, transformed_data)
+#
+# def perform_data_validation(self, activation):
+# """Validate transformed data"""
+# process = activation.process
+# sync_config = process.sync_configuration
+#
+# # Validate data
+# validation_results = self.validate_sync_data(sync_config)
+#
+# # Mark data validated
+# process.data_validated = True
+# process.save()
+#
+# # Store validation results
+# self.store_validation_results(sync_config, validation_results)
+#
+# def perform_data_loading(self, activation):
+# """Load data into target system"""
+# process = activation.process
+# sync_config = process.sync_configuration
+#
+# # Load data
+# loading_results = self.load_sync_data(sync_config)
+#
+# # Mark data loaded
+# process.data_loaded = True
+# process.save()
+#
+# # Store loading results
+# self.store_loading_results(sync_config, loading_results)
+#
+# def handle_data_conflicts(self, activation):
+# """Handle data conflicts and duplicates"""
+# process = activation.process
+# sync_config = process.sync_configuration
+#
+# # Resolve conflicts
+# conflict_results = self.resolve_data_conflicts(sync_config)
+#
+# # Mark conflicts resolved
+# process.conflicts_resolved = True
+# process.save()
+#
+# # Store conflict resolution results
+# self.store_conflict_results(sync_config, conflict_results)
+#
+# def finalize_data_synchronization(self, activation):
+# """Finalize the data synchronization process"""
+# process = activation.process
+# sync_config = process.sync_configuration
+#
+# # Mark sync completed
+# process.sync_completed = True
+# process.save()
+#
+# # Send completion notifications
+# self.notify_sync_completion(sync_config)
+#
+# # Update sync statistics
+# self.update_sync_statistics(sync_config)
+#
+# # Schedule next sync if recurring
+# self.schedule_next_sync(sync_config)
+#
+# def end_data_synchronization(self, activation):
+# """End the data synchronization workflow"""
+# process = activation.process
+#
+# # Generate sync summary
+# self.generate_sync_summary(process.sync_configuration)
+#
+# # Helper methods
+# def notify_sync_start(self, sync_config):
+# """Notify sync start"""
+# # This would notify relevant parties
+# pass
+#
+# def create_sync_execution(self, sync_config):
+# """Create sync execution record"""
+# # This would create execution record
+# pass
+#
+# def prepare_sync_environment(self, sync_config):
+# """Prepare synchronization environment"""
+# # This would prepare sync environment
+# pass
+#
+# def extract_source_data(self, sync_config):
+# """Extract data from source system"""
+# # This would extract data from source
+# return {'status': 'extracted', 'records': 1000}
+#
+# def store_extracted_data(self, sync_config, data):
+# """Store extracted data"""
+# # This would store extracted data
+# pass
+#
+# def transform_sync_data(self, sync_config):
+# """Transform data according to mapping"""
+# # This would transform data
+# return {'status': 'transformed', 'records': 1000}
+#
+# def store_transformed_data(self, sync_config, data):
+# """Store transformed data"""
+# # This would store transformed data
+# pass
+#
+# def validate_sync_data(self, sync_config):
+# """Validate transformed data"""
+# # This would validate data
+# return {'status': 'valid', 'errors': []}
+#
+# def store_validation_results(self, sync_config, results):
+# """Store validation results"""
+# # This would store validation results
+# pass
+#
+# def load_sync_data(self, sync_config):
+# """Load data into target system"""
+# # This would load data
+# return {'status': 'loaded', 'records': 1000}
+#
+# def store_loading_results(self, sync_config, results):
+# """Store loading results"""
+# # This would store loading results
+# pass
+#
+# def resolve_data_conflicts(self, sync_config):
+# """Resolve data conflicts"""
+# # This would resolve conflicts
+# return {'status': 'resolved', 'conflicts': 0}
+#
+# def store_conflict_results(self, sync_config, results):
+# """Store conflict resolution results"""
+# # This would store conflict results
+# pass
+#
+# def notify_sync_completion(self, sync_config):
+# """Notify sync completion"""
+# # This would notify completion
+# pass
+#
+# def update_sync_statistics(self, sync_config):
+# """Update synchronization statistics"""
+# # This would update sync stats
+# pass
+#
+# def schedule_next_sync(self, sync_config):
+# """Schedule next synchronization"""
+# if sync_config.is_recurring:
+# # Schedule next sync
+# data_sync.apply_async(
+# args=[sync_config.sync_id],
+# countdown=sync_config.sync_interval_seconds
+# )
+#
+# def generate_sync_summary(self, sync_config):
+# """Generate synchronization summary"""
+# # This would generate sync summary
+# pass
+#
+#
+# class WebhookManagementProcess(Process):
+# """
+# Viewflow process model for webhook management
+# """
+# webhook_endpoint = ModelField(WebhookEndpoint, help_text='Associated webhook endpoint')
+#
+# # Process status tracking
+# webhook_created = models.BooleanField(default=False)
+# security_configured = models.BooleanField(default=False)
+# testing_completed = models.BooleanField(default=False)
+# monitoring_setup = models.BooleanField(default=False)
+# webhook_activated = models.BooleanField(default=False)
+#
+# class Meta:
+# verbose_name = 'Webhook Management Process'
+# verbose_name_plural = 'Webhook Management Processes'
+#
+#
+# class WebhookManagementFlow(Flow):
+# """
+# Webhook Management Workflow
+#
+# This flow manages webhook endpoint creation, configuration,
+# testing, and activation for receiving external data.
+# """
+#
+# process_class = WebhookManagementProcess
+#
+# # Flow definition
+# start = (
+# flow_func(this.start_webhook_management)
+# .Next(this.create_webhook)
+# )
+#
+# create_webhook = (
+# flow_view(WebhookManagementView)
+# .Permission('integration.can_manage_webhooks')
+# .Next(this.configure_security)
+# )
+#
+# configure_security = (
+# flow_func(this.setup_webhook_security)
+# .Next(this.test_webhook)
+# )
+#
+# test_webhook = (
+# flow_func(this.perform_webhook_testing)
+# .Next(this.setup_monitoring)
+# )
+#
+# setup_monitoring = (
+# flow_func(this.configure_webhook_monitoring)
+# .Next(this.activate_webhook)
+# )
+#
+# activate_webhook = (
+# flow_func(this.activate_webhook_endpoint)
+# .Next(this.end)
+# )
+#
+# end = flow_func(this.end_webhook_management)
+#
+# # Flow functions
+# def start_webhook_management(self, activation):
+# """Initialize the webhook management process"""
+# process = activation.process
+# webhook = process.webhook_endpoint
+#
+# # Send webhook creation notification
+# self.notify_webhook_creation(webhook)
+#
+# def setup_webhook_security(self, activation):
+# """Setup webhook security configuration"""
+# process = activation.process
+# webhook = process.webhook_endpoint
+#
+# # Configure security settings
+# self.configure_webhook_security(webhook)
+#
+# # Mark security configured
+# process.security_configured = True
+# process.save()
+#
+# def perform_webhook_testing(self, activation):
+# """Perform webhook testing"""
+# process = activation.process
+# webhook = process.webhook_endpoint
+#
+# # Test webhook functionality
+# test_results = self.test_webhook_functionality(webhook)
+#
+# # Mark testing completed
+# process.testing_completed = True
+# process.save()
+#
+# # Store test results
+# self.store_webhook_test_results(webhook, test_results)
+#
+# def configure_webhook_monitoring(self, activation):
+# """Configure webhook monitoring"""
+# process = activation.process
+# webhook = process.webhook_endpoint
+#
+# # Setup monitoring
+# self.setup_webhook_monitoring(webhook)
+#
+# # Mark monitoring setup
+# process.monitoring_setup = True
+# process.save()
+#
+# def activate_webhook_endpoint(self, activation):
+# """Activate webhook endpoint"""
+# process = activation.process
+# webhook = process.webhook_endpoint
+#
+# # Activate webhook
+# webhook.is_active = True
+# webhook.save()
+#
+# # Mark webhook activated
+# process.webhook_activated = True
+# process.save()
+#
+# # Send activation notifications
+# self.notify_webhook_activation(webhook)
+#
+# def end_webhook_management(self, activation):
+# """End the webhook management workflow"""
+# process = activation.process
+#
+# # Generate webhook summary
+# self.generate_webhook_summary(process.webhook_endpoint)
+#
+# # Helper methods
+# def notify_webhook_creation(self, webhook):
+# """Notify webhook creation"""
+# integration_team = User.objects.filter(groups__name='Integration Team')
+# for staff in integration_team:
+# send_mail(
+# subject=f'Webhook Created: {webhook.name}',
+# message=f'Webhook endpoint "{webhook.name}" has been created.',
+# from_email='integration@hospital.com',
+# recipient_list=[staff.email],
+# fail_silently=True
+# )
+#
+# def configure_webhook_security(self, webhook):
+# """Configure webhook security"""
+# # This would configure security settings
+# pass
+#
+# def test_webhook_functionality(self, webhook):
+# """Test webhook functionality"""
+# # This would test webhook
+# return {'status': 'passed', 'tests': 5}
+#
+# def store_webhook_test_results(self, webhook, results):
+# """Store webhook test results"""
+# # This would store test results
+# pass
+#
+# def setup_webhook_monitoring(self, webhook):
+# """Setup webhook monitoring"""
+# # This would setup monitoring
+# pass
+#
+# def notify_webhook_activation(self, webhook):
+# """Notify webhook activation"""
+# # This would notify activation
+# pass
+#
+# def generate_webhook_summary(self, webhook):
+# """Generate webhook summary"""
+# # This would generate webhook summary
+# pass
+#
+#
+# # Celery tasks for background processing
+# @celery.job
+# def system_health_check(system_id):
+# """Background task for system health monitoring"""
+# try:
+# system = ExternalSystem.objects.get(system_id=system_id)
+#
+# # Perform health check
+# # This would perform system health check
+#
+# # Schedule next health check
+# system_health_check.apply_async(
+# args=[system_id],
+# countdown=300 # 5 minutes
+# )
+#
+# return True
+# except Exception:
+# return False
+#
+#
+# @celery.job
+# def data_sync(sync_id):
+# """Background task for data synchronization"""
+# try:
+# sync_config = SyncConfiguration.objects.get(sync_id=sync_id)
+#
+# # Start data synchronization workflow
+# # This would start the data sync workflow
+#
+# return True
+# except Exception:
+# return False
+#
+#
+# @celery.job
+# def webhook_health_check():
+# """Background task for webhook health monitoring"""
+# try:
+# # This would monitor webhook health
+# return True
+# except Exception:
+# return False
+#
+#
+# @celery.job
+# def integration_performance_monitoring():
+# """Background task for integration performance monitoring"""
+# try:
+# # This would monitor integration performance
+# return True
+# except Exception:
+# return False
+#
+#
+# @celery.job
+# def cleanup_integration_logs():
+# """Background task to cleanup old integration logs"""
+# try:
+# # This would cleanup old logs
+# return True
+# except Exception:
+# return False
+#
diff --git a/inventory/__pycache__/flows.cpython-312.pyc b/inventory/__pycache__/flows.cpython-312.pyc
new file mode 100644
index 00000000..98e4ebf1
Binary files /dev/null and b/inventory/__pycache__/flows.cpython-312.pyc differ
diff --git a/inventory/flows.py b/inventory/flows.py
new file mode 100644
index 00000000..845c5d5e
--- /dev/null
+++ b/inventory/flows.py
@@ -0,0 +1,905 @@
+# """
+# Viewflow workflows for inventory app.
+# Provides inventory management, procurement, and supply chain workflows.
+# """
+#
+# from viewflow import Flow, lock
+# from viewflow.base import this, flow_func
+# from viewflow.contrib import celery
+# from viewflow.decorators import flow_view
+# from viewflow.fields import CharField, ModelField
+# from viewflow.forms import ModelForm
+# from viewflow.views import CreateProcessView, UpdateProcessView
+# from viewflow.models import Process, Task
+# from django.contrib.auth.models import User
+# from django.urls import reverse_lazy
+# from django.utils import timezone
+# from django.db import transaction
+# from django.core.mail import send_mail
+#
+# from .models import InventoryItem, PurchaseOrder, PurchaseOrderItem, Supplier, InventoryStock, InventoryLocation
+# from .views import (
+# PurchaseRequestView, VendorSelectionView, PurchaseOrderCreationView,
+# ApprovalView, OrderSubmissionView, ReceivingView, InspectionView,
+# StockUpdateView, InvoiceMatchingView, PaymentProcessingView,
+# StockReplenishmentView, StockTransferView, StockAdjustmentView,
+# CycleCountView, InventoryAuditView
+# )
+#
+#
+# class ProcurementProcess(Process):
+# """
+# Viewflow process model for procurement
+# """
+# purchase_order = ModelField(PurchaseOrder, help_text='Associated purchase order')
+#
+# # Process status tracking
+# request_submitted = models.BooleanField(default=False)
+# vendor_selected = models.BooleanField(default=False)
+# order_created = models.BooleanField(default=False)
+# order_approved = models.BooleanField(default=False)
+# order_sent = models.BooleanField(default=False)
+# goods_received = models.BooleanField(default=False)
+# invoice_processed = models.BooleanField(default=False)
+# payment_completed = models.BooleanField(default=False)
+# procurement_closed = models.BooleanField(default=False)
+#
+# class Meta:
+# verbose_name = 'Procurement Process'
+# verbose_name_plural = 'Procurement Processes'
+#
+#
+# class ProcurementFlow(Flow):
+# """
+# Procurement Workflow
+#
+# This flow manages the complete procurement process from purchase
+# request through payment and order closure.
+# """
+#
+# process_class = ProcurementProcess
+#
+# # Flow definition
+# start = (
+# flow_func(this.start_procurement)
+# .Next(this.submit_request)
+# )
+#
+# submit_request = (
+# flow_view(PurchaseRequestView)
+# .Permission('inventory.can_submit_purchase_requests')
+# .Next(this.select_vendor)
+# )
+#
+# select_vendor = (
+# flow_view(VendorSelectionView)
+# .Permission('inventory.can_select_vendors')
+# .Next(this.create_order)
+# )
+#
+# create_order = (
+# flow_view(PurchaseOrderCreationView)
+# .Permission('inventory.can_create_purchase_orders')
+# .Next(this.approve_order)
+# )
+#
+# approve_order = (
+# flow_view(ApprovalView)
+# .Permission('inventory.can_approve_purchase_orders')
+# .Next(this.send_order)
+# )
+#
+# send_order = (
+# flow_view(OrderSubmissionView)
+# .Permission('inventory.can_send_purchase_orders')
+# .Next(this.receive_goods)
+# )
+#
+# receive_goods = (
+# flow_view(ReceivingView)
+# .Permission('inventory.can_receive_goods')
+# .Next(this.inspect_goods)
+# )
+#
+# inspect_goods = (
+# flow_view(InspectionView)
+# .Permission('inventory.can_inspect_goods')
+# .Next(this.update_stock)
+# )
+#
+# update_stock = (
+# flow_view(StockUpdateView)
+# .Permission('inventory.can_update_stock')
+# .Next(this.process_invoice)
+# )
+#
+# process_invoice = (
+# flow_view(InvoiceMatchingView)
+# .Permission('inventory.can_process_invoices')
+# .Next(this.process_payment)
+# )
+#
+# process_payment = (
+# flow_view(PaymentProcessingView)
+# .Permission('inventory.can_process_payments')
+# .Next(this.close_order)
+# )
+#
+# close_order = (
+# flow_func(this.complete_procurement)
+# .Next(this.end)
+# )
+#
+# end = flow_func(this.end_procurement)
+#
+# # Flow functions
+# def start_procurement(self, activation):
+# """Initialize the procurement process"""
+# process = activation.process
+# order = process.purchase_order
+#
+# # Update order status
+# order.status = 'DRAFT'
+# order.save()
+#
+# # Send notification to procurement staff
+# self.notify_procurement_staff(order)
+#
+# # Check for urgent orders
+# if order.priority in ['HIGH', 'URGENT']:
+# self.notify_urgent_procurement(order)
+#
+# def complete_procurement(self, activation):
+# """Finalize the procurement process"""
+# process = activation.process
+# order = process.purchase_order
+#
+# # Update order status
+# order.status = 'CLOSED'
+# order.save()
+#
+# # Mark process as completed
+# process.procurement_closed = True
+# process.save()
+#
+# # Send completion notifications
+# self.notify_procurement_completion(order)
+#
+# # Update supplier performance metrics
+# self.update_supplier_performance(order)
+#
+# # Update procurement metrics
+# self.update_procurement_metrics(order)
+#
+# def end_procurement(self, activation):
+# """End the procurement workflow"""
+# process = activation.process
+#
+# # Generate procurement summary report
+# self.generate_procurement_summary(process.purchase_order)
+#
+# # Helper methods
+# def notify_procurement_staff(self, order):
+# """Notify procurement staff of new order"""
+# from django.contrib.auth.models import Group
+#
+# procurement_staff = User.objects.filter(
+# groups__name='Procurement Staff'
+# )
+#
+# for staff in procurement_staff:
+# send_mail(
+# subject=f'New Purchase Order: {order.po_number}',
+# message=f'New purchase order for {order.supplier.name} requires processing.',
+# from_email='procurement@hospital.com',
+# recipient_list=[staff.email],
+# fail_silently=True
+# )
+#
+# def notify_urgent_procurement(self, order):
+# """Notify of urgent procurement"""
+# procurement_managers = User.objects.filter(
+# groups__name='Procurement Managers'
+# )
+#
+# for manager in procurement_managers:
+# send_mail(
+# subject=f'URGENT Purchase Order: {order.po_number}',
+# message=f'{order.get_priority_display()} purchase order requires immediate attention.',
+# from_email='procurement@hospital.com',
+# recipient_list=[manager.email],
+# fail_silently=True
+# )
+#
+# def notify_procurement_completion(self, order):
+# """Notify procurement completion"""
+# # Notify requestor
+# if order.requested_by and order.requested_by.email:
+# send_mail(
+# subject=f'Purchase Order Complete: {order.po_number}',
+# message=f'Your purchase order has been completed and goods received.',
+# from_email='procurement@hospital.com',
+# recipient_list=[order.requested_by.email],
+# fail_silently=True
+# )
+#
+# def update_supplier_performance(self, order):
+# """Update supplier performance metrics"""
+# supplier = order.supplier
+#
+# # Calculate on-time delivery
+# if order.actual_delivery_date and order.promised_delivery_date:
+# if order.actual_delivery_date <= order.promised_delivery_date:
+# # Update on-time delivery rate
+# pass
+#
+# # This would update comprehensive supplier metrics
+# pass
+#
+# def update_procurement_metrics(self, order):
+# """Update procurement performance metrics"""
+# # This would update procurement cycle time and other metrics
+# pass
+#
+# def generate_procurement_summary(self, order):
+# """Generate procurement summary report"""
+# # This would generate a comprehensive procurement report
+# pass
+#
+#
+# class InventoryReplenishmentProcess(Process):
+# """
+# Viewflow process model for inventory replenishment
+# """
+# inventory_item = ModelField(InventoryItem, help_text='Associated inventory item')
+#
+# # Process status tracking
+# reorder_triggered = models.BooleanField(default=False)
+# demand_analyzed = models.BooleanField(default=False)
+# quantity_calculated = models.BooleanField(default=False)
+# supplier_contacted = models.BooleanField(default=False)
+# order_placed = models.BooleanField(default=False)
+# delivery_scheduled = models.BooleanField(default=False)
+# stock_replenished = models.BooleanField(default=False)
+#
+# class Meta:
+# verbose_name = 'Inventory Replenishment Process'
+# verbose_name_plural = 'Inventory Replenishment Processes'
+#
+#
+# class InventoryReplenishmentFlow(Flow):
+# """
+# Inventory Replenishment Workflow
+#
+# This flow manages automatic and manual inventory replenishment
+# including demand analysis and supplier coordination.
+# """
+#
+# process_class = InventoryReplenishmentProcess
+#
+# # Flow definition
+# start = (
+# flow_func(this.start_replenishment)
+# .Next(this.trigger_reorder)
+# )
+#
+# trigger_reorder = (
+# flow_func(this.check_reorder_point)
+# .Next(this.analyze_demand)
+# )
+#
+# analyze_demand = (
+# flow_view(DemandAnalysisView)
+# .Permission('inventory.can_analyze_demand')
+# .Next(this.calculate_quantity)
+# )
+#
+# calculate_quantity = (
+# flow_view(QuantityCalculationView)
+# .Permission('inventory.can_calculate_quantities')
+# .Next(this.contact_supplier)
+# )
+#
+# contact_supplier = (
+# flow_view(SupplierContactView)
+# .Permission('inventory.can_contact_suppliers')
+# .Next(this.place_order)
+# )
+#
+# place_order = (
+# flow_view(OrderPlacementView)
+# .Permission('inventory.can_place_orders')
+# .Next(this.schedule_delivery)
+# )
+#
+# schedule_delivery = (
+# flow_view(DeliverySchedulingView)
+# .Permission('inventory.can_schedule_deliveries')
+# .Next(this.replenish_stock)
+# )
+#
+# replenish_stock = (
+# flow_func(this.complete_replenishment)
+# .Next(this.end)
+# )
+#
+# end = flow_func(this.end_replenishment)
+#
+# # Flow functions
+# def start_replenishment(self, activation):
+# """Initialize the replenishment process"""
+# process = activation.process
+# item = process.inventory_item
+#
+# # Send notification to inventory staff
+# self.notify_replenishment_needed(item)
+#
+# def check_reorder_point(self, activation):
+# """Check if item has reached reorder point"""
+# process = activation.process
+# item = process.inventory_item
+#
+# # Check current stock levels
+# current_stock = item.total_stock
+#
+# if current_stock <= item.reorder_point:
+# process.reorder_triggered = True
+# process.save()
+#
+# # Send urgent notification if below safety stock
+# if current_stock <= item.safety_stock:
+# self.notify_critical_stock(item)
+#
+# def complete_replenishment(self, activation):
+# """Finalize the replenishment process"""
+# process = activation.process
+# item = process.inventory_item
+#
+# # Mark process as completed
+# process.stock_replenished = True
+# process.save()
+#
+# # Send completion notifications
+# self.notify_replenishment_completion(item)
+#
+# # Update inventory metrics
+# self.update_inventory_metrics(item)
+#
+# def end_replenishment(self, activation):
+# """End the replenishment workflow"""
+# process = activation.process
+#
+# # Generate replenishment summary
+# self.generate_replenishment_summary(process.inventory_item)
+#
+# # Helper methods
+# def notify_replenishment_needed(self, item):
+# """Notify inventory staff of replenishment need"""
+# inventory_staff = User.objects.filter(
+# groups__name='Inventory Staff'
+# )
+#
+# for staff in inventory_staff:
+# send_mail(
+# subject=f'Replenishment Needed: {item.item_name}',
+# message=f'Item {item.item_code} has reached reorder point.',
+# from_email='inventory@hospital.com',
+# recipient_list=[staff.email],
+# fail_silently=True
+# )
+#
+# def notify_critical_stock(self, item):
+# """Notify of critical stock levels"""
+# inventory_managers = User.objects.filter(
+# groups__name='Inventory Managers'
+# )
+#
+# for manager in inventory_managers:
+# send_mail(
+# subject=f'CRITICAL STOCK: {item.item_name}',
+# message=f'Item {item.item_code} is below safety stock level.',
+# from_email='inventory@hospital.com',
+# recipient_list=[manager.email],
+# fail_silently=True
+# )
+#
+# def notify_replenishment_completion(self, item):
+# """Notify replenishment completion"""
+# # This would notify relevant staff
+# pass
+#
+# def update_inventory_metrics(self, item):
+# """Update inventory performance metrics"""
+# # This would update inventory turnover and other metrics
+# pass
+#
+# def generate_replenishment_summary(self, item):
+# """Generate replenishment summary"""
+# # This would generate replenishment summary
+# pass
+#
+#
+# class StockMovementProcess(Process):
+# """
+# Viewflow process model for stock movements
+# """
+# movement_type = CharField(max_length=20, help_text='Type of stock movement')
+# item_id = CharField(max_length=50, help_text='Item identifier')
+#
+# # Process status tracking
+# movement_initiated = models.BooleanField(default=False)
+# authorization_verified = models.BooleanField(default=False)
+# stock_reserved = models.BooleanField(default=False)
+# movement_executed = models.BooleanField(default=False)
+# documentation_completed = models.BooleanField(default=False)
+# movement_verified = models.BooleanField(default=False)
+#
+# class Meta:
+# verbose_name = 'Stock Movement Process'
+# verbose_name_plural = 'Stock Movement Processes'
+#
+#
+# class StockMovementFlow(Flow):
+# """
+# Stock Movement Workflow
+#
+# This flow manages stock transfers, adjustments, and other
+# inventory movements with proper authorization and tracking.
+# """
+#
+# process_class = StockMovementProcess
+#
+# # Flow definition
+# start = (
+# flow_func(this.start_movement)
+# .Next(this.initiate_movement)
+# )
+#
+# initiate_movement = (
+# flow_view(MovementInitiationView)
+# .Permission('inventory.can_initiate_movements')
+# .Next(this.verify_authorization)
+# )
+#
+# verify_authorization = (
+# flow_view(AuthorizationVerificationView)
+# .Permission('inventory.can_verify_authorization')
+# .Next(this.reserve_stock)
+# )
+#
+# reserve_stock = (
+# flow_view(StockReservationView)
+# .Permission('inventory.can_reserve_stock')
+# .Next(this.execute_movement)
+# )
+#
+# execute_movement = (
+# flow_view(MovementExecutionView)
+# .Permission('inventory.can_execute_movements')
+# .Next(this.complete_documentation)
+# )
+#
+# complete_documentation = (
+# flow_view(DocumentationView)
+# .Permission('inventory.can_complete_documentation')
+# .Next(this.verify_movement)
+# )
+#
+# verify_movement = (
+# flow_view(MovementVerificationView)
+# .Permission('inventory.can_verify_movements')
+# .Next(this.finalize_movement)
+# )
+#
+# finalize_movement = (
+# flow_func(this.complete_movement)
+# .Next(this.end)
+# )
+#
+# end = flow_func(this.end_movement)
+#
+# # Flow functions
+# def start_movement(self, activation):
+# """Initialize the stock movement process"""
+# process = activation.process
+#
+# # Send notification to inventory staff
+# self.notify_movement_initiated(process.movement_type, process.item_id)
+#
+# def complete_movement(self, activation):
+# """Finalize the stock movement process"""
+# process = activation.process
+#
+# # Mark process as completed
+# process.movement_verified = True
+# process.save()
+#
+# # Send completion notifications
+# self.notify_movement_completion(process.movement_type, process.item_id)
+#
+# # Update inventory records
+# self.update_inventory_records(process.movement_type, process.item_id)
+#
+# def end_movement(self, activation):
+# """End the stock movement workflow"""
+# process = activation.process
+#
+# # Generate movement summary
+# self.generate_movement_summary(process.movement_type, process.item_id)
+#
+# # Helper methods
+# def notify_movement_initiated(self, movement_type, item_id):
+# """Notify inventory staff of movement initiation"""
+# inventory_staff = User.objects.filter(
+# groups__name='Inventory Staff'
+# )
+#
+# for staff in inventory_staff:
+# send_mail(
+# subject=f'Stock Movement Initiated: {item_id}',
+# message=f'{movement_type} movement initiated for item {item_id}.',
+# from_email='inventory@hospital.com',
+# recipient_list=[staff.email],
+# fail_silently=True
+# )
+#
+# def notify_movement_completion(self, movement_type, item_id):
+# """Notify movement completion"""
+# # This would notify relevant staff
+# pass
+#
+# def update_inventory_records(self, movement_type, item_id):
+# """Update inventory records"""
+# # This would update inventory records
+# pass
+#
+# def generate_movement_summary(self, movement_type, item_id):
+# """Generate movement summary"""
+# # This would generate movement summary
+# pass
+#
+#
+# class InventoryAuditProcess(Process):
+# """
+# Viewflow process model for inventory audits
+# """
+# audit_type = CharField(max_length=20, help_text='Type of audit')
+# location_id = CharField(max_length=50, help_text='Location identifier')
+#
+# # Process status tracking
+# audit_scheduled = models.BooleanField(default=False)
+# audit_team_assigned = models.BooleanField(default=False)
+# physical_count_completed = models.BooleanField(default=False)
+# discrepancies_identified = models.BooleanField(default=False)
+# adjustments_made = models.BooleanField(default=False)
+# audit_report_generated = models.BooleanField(default=False)
+# audit_completed = models.BooleanField(default=False)
+#
+# class Meta:
+# verbose_name = 'Inventory Audit Process'
+# verbose_name_plural = 'Inventory Audit Processes'
+#
+#
+# class InventoryAuditFlow(Flow):
+# """
+# Inventory Audit Workflow
+#
+# This flow manages inventory audits including cycle counts,
+# physical inventories, and discrepancy resolution.
+# """
+#
+# process_class = InventoryAuditProcess
+#
+# # Flow definition
+# start = (
+# flow_func(this.start_audit)
+# .Next(this.schedule_audit)
+# )
+#
+# schedule_audit = (
+# flow_view(AuditSchedulingView)
+# .Permission('inventory.can_schedule_audits')
+# .Next(this.assign_team)
+# )
+#
+# assign_team = (
+# flow_view(TeamAssignmentView)
+# .Permission('inventory.can_assign_audit_teams')
+# .Next(this.conduct_count)
+# )
+#
+# conduct_count = (
+# flow_view(CycleCountView)
+# .Permission('inventory.can_conduct_counts')
+# .Next(this.identify_discrepancies)
+# )
+#
+# identify_discrepancies = (
+# flow_func(this.analyze_discrepancies)
+# .Next(this.make_adjustments)
+# )
+#
+# make_adjustments = (
+# flow_view(InventoryAdjustmentView)
+# .Permission('inventory.can_make_adjustments')
+# .Next(this.generate_report)
+# )
+#
+# generate_report = (
+# flow_view(AuditReportView)
+# .Permission('inventory.can_generate_audit_reports')
+# .Next(this.complete_audit)
+# )
+#
+# complete_audit = (
+# flow_func(this.finalize_audit)
+# .Next(this.end)
+# )
+#
+# end = flow_func(this.end_audit)
+#
+# # Flow functions
+# def start_audit(self, activation):
+# """Initialize the audit process"""
+# process = activation.process
+#
+# # Send notification to audit team
+# self.notify_audit_scheduled(process.audit_type, process.location_id)
+#
+# def analyze_discrepancies(self, activation):
+# """Analyze inventory discrepancies"""
+# process = activation.process
+#
+# # Check for discrepancies
+# discrepancies = self.check_discrepancies(process.location_id)
+#
+# if discrepancies:
+# process.discrepancies_identified = True
+# process.save()
+#
+# # Alert audit supervisor
+# self.alert_audit_supervisor(process.location_id, discrepancies)
+#
+# def finalize_audit(self, activation):
+# """Finalize the audit process"""
+# process = activation.process
+#
+# # Mark audit as completed
+# process.audit_completed = True
+# process.save()
+#
+# # Send completion notifications
+# self.notify_audit_completion(process.audit_type, process.location_id)
+#
+# # Update audit metrics
+# self.update_audit_metrics(process.audit_type, process.location_id)
+#
+# def end_audit(self, activation):
+# """End the audit workflow"""
+# process = activation.process
+#
+# # Generate audit summary
+# self.generate_audit_summary(process.audit_type, process.location_id)
+#
+# # Helper methods
+# def notify_audit_scheduled(self, audit_type, location_id):
+# """Notify audit team of scheduled audit"""
+# audit_staff = User.objects.filter(
+# groups__name='Audit Staff'
+# )
+#
+# for staff in audit_staff:
+# send_mail(
+# subject=f'Audit Scheduled: {location_id}',
+# message=f'{audit_type} audit scheduled for location {location_id}.',
+# from_email='audit@hospital.com',
+# recipient_list=[staff.email],
+# fail_silently=True
+# )
+#
+# def check_discrepancies(self, location_id):
+# """Check for inventory discrepancies"""
+# # This would implement discrepancy checking logic
+# return []
+#
+# def alert_audit_supervisor(self, location_id, discrepancies):
+# """Alert audit supervisor of discrepancies"""
+# supervisors = User.objects.filter(
+# groups__name='Audit Supervisors'
+# )
+#
+# for supervisor in supervisors:
+# send_mail(
+# subject=f'Audit Discrepancies Found: {location_id}',
+# message=f'Inventory discrepancies identified during audit.',
+# from_email='audit@hospital.com',
+# recipient_list=[supervisor.email],
+# fail_silently=True
+# )
+#
+# def notify_audit_completion(self, audit_type, location_id):
+# """Notify audit completion"""
+# # This would notify relevant parties
+# pass
+#
+# def update_audit_metrics(self, audit_type, location_id):
+# """Update audit metrics"""
+# # This would update audit performance metrics
+# pass
+#
+# def generate_audit_summary(self, audit_type, location_id):
+# """Generate audit summary"""
+# # This would generate audit summary
+# pass
+#
+#
+# class SupplierManagementProcess(Process):
+# """
+# Viewflow process model for supplier management
+# """
+# supplier = ModelField(Supplier, help_text='Associated supplier')
+#
+# # Process status tracking
+# supplier_onboarded = models.BooleanField(default=False)
+# qualifications_verified = models.BooleanField(default=False)
+# contracts_negotiated = models.BooleanField(default=False)
+# performance_monitored = models.BooleanField(default=False)
+# relationship_maintained = models.BooleanField(default=False)
+#
+# class Meta:
+# verbose_name = 'Supplier Management Process'
+# verbose_name_plural = 'Supplier Management Processes'
+#
+#
+# class SupplierManagementFlow(Flow):
+# """
+# Supplier Management Workflow
+#
+# This flow manages supplier onboarding, qualification,
+# performance monitoring, and relationship management.
+# """
+#
+# process_class = SupplierManagementProcess
+#
+# # Flow definition
+# start = (
+# flow_func(this.start_supplier_management)
+# .Next(this.onboard_supplier)
+# )
+#
+# onboard_supplier = (
+# flow_view(SupplierOnboardingView)
+# .Permission('inventory.can_onboard_suppliers')
+# .Next(this.verify_qualifications)
+# )
+#
+# verify_qualifications = (
+# flow_view(QualificationVerificationView)
+# .Permission('inventory.can_verify_qualifications')
+# .Next(this.negotiate_contracts)
+# )
+#
+# negotiate_contracts = (
+# flow_view(ContractNegotiationView)
+# .Permission('inventory.can_negotiate_contracts')
+# .Next(this.monitor_performance)
+# )
+#
+# monitor_performance = (
+# flow_view(PerformanceMonitoringView)
+# .Permission('inventory.can_monitor_performance')
+# .Next(this.maintain_relationship)
+# )
+#
+# maintain_relationship = (
+# flow_func(this.complete_supplier_management)
+# .Next(this.end)
+# )
+#
+# end = flow_func(this.end_supplier_management)
+#
+# # Flow functions
+# def start_supplier_management(self, activation):
+# """Initialize the supplier management process"""
+# process = activation.process
+# supplier = process.supplier
+#
+# # Send notification to procurement team
+# self.notify_supplier_onboarding(supplier)
+#
+# def complete_supplier_management(self, activation):
+# """Finalize the supplier management process"""
+# process = activation.process
+# supplier = process.supplier
+#
+# # Mark process as completed
+# process.relationship_maintained = True
+# process.save()
+#
+# # Send completion notifications
+# self.notify_supplier_management_completion(supplier)
+#
+# def end_supplier_management(self, activation):
+# """End the supplier management workflow"""
+# process = activation.process
+#
+# # Generate supplier management summary
+# self.generate_supplier_summary(process.supplier)
+#
+# # Helper methods
+# def notify_supplier_onboarding(self, supplier):
+# """Notify procurement team of supplier onboarding"""
+# procurement_staff = User.objects.filter(
+# groups__name='Procurement Staff'
+# )
+#
+# for staff in procurement_staff:
+# send_mail(
+# subject=f'Supplier Onboarding: {supplier.name}',
+# message=f'New supplier {supplier.name} requires onboarding.',
+# from_email='procurement@hospital.com',
+# recipient_list=[staff.email],
+# fail_silently=True
+# )
+#
+# def notify_supplier_management_completion(self, supplier):
+# """Notify supplier management completion"""
+# # This would notify relevant parties
+# pass
+#
+# def generate_supplier_summary(self, supplier):
+# """Generate supplier management summary"""
+# # This would generate supplier summary
+# pass
+#
+#
+# # Celery tasks for background processing
+# @celery.job
+# def auto_reorder_items():
+# """Background task to automatically reorder items"""
+# try:
+# # This would check reorder points and create orders
+# return True
+# except Exception:
+# return False
+#
+#
+# @celery.job
+# def monitor_expiring_items():
+# """Background task to monitor expiring inventory items"""
+# try:
+# # This would identify items nearing expiration
+# return True
+# except Exception:
+# return False
+#
+#
+# @celery.job
+# def generate_inventory_reports():
+# """Background task to generate inventory reports"""
+# try:
+# # This would generate daily inventory reports
+# return True
+# except Exception:
+# return False
+#
+#
+# @celery.job
+# def update_supplier_performance():
+# """Background task to update supplier performance metrics"""
+# try:
+# # This would calculate supplier performance metrics
+# return True
+# except Exception:
+# return False
+#
+#
+# @celery.job
+# def schedule_cycle_counts():
+# """Background task to schedule cycle counts"""
+# try:
+# # This would schedule regular cycle counts
+# return True
+# except Exception:
+# return False
+#
diff --git a/laboratory/__pycache__/flows.cpython-312.pyc b/laboratory/__pycache__/flows.cpython-312.pyc
new file mode 100644
index 00000000..55c792fd
Binary files /dev/null and b/laboratory/__pycache__/flows.cpython-312.pyc differ
diff --git a/laboratory/flows.py b/laboratory/flows.py
new file mode 100644
index 00000000..855bc531
--- /dev/null
+++ b/laboratory/flows.py
@@ -0,0 +1,523 @@
+# """
+# Viewflow workflows for laboratory app.
+# Provides lab test ordering, specimen processing, and result reporting workflows.
+# """
+#
+# from viewflow import Flow, lock
+# from viewflow.base import this, flow_func
+# from viewflow.contrib import celery
+# from viewflow.decorators import flow_view
+# from viewflow.fields import CharField, ModelField
+# from viewflow.forms import ModelForm
+# from viewflow.views import CreateProcessView, UpdateProcessView
+# from viewflow.models import Process, Task
+# from django.contrib.auth.models import User
+# from django.urls import reverse_lazy
+# from django.utils import timezone
+# from django.db import transaction
+# from django.core.mail import send_mail
+#
+# from .models import LabOrder, Specimen, LabResult, LabTest
+# from .views import (
+# LabOrderCreationView, SpecimenCollectionView, SpecimenReceiptView,
+# TestProcessingView, ResultEntryView, ResultVerificationView,
+# ResultReportingView
+# )
+#
+#
+# class LabOrderProcess(Process):
+# """
+# Viewflow process model for laboratory test orders
+# """
+# lab_order = ModelField(LabOrder, help_text='Associated lab order')
+#
+# # Process status tracking
+# order_created = models.BooleanField(default=False)
+# specimen_collected = models.BooleanField(default=False)
+# specimen_received = models.BooleanField(default=False)
+# tests_processed = models.BooleanField(default=False)
+# results_verified = models.BooleanField(default=False)
+# results_reported = models.BooleanField(default=False)
+#
+# class Meta:
+# verbose_name = 'Lab Order Process'
+# verbose_name_plural = 'Lab Order Processes'
+#
+#
+# class LabOrderFlow(Flow):
+# """
+# Laboratory Test Order Workflow
+#
+# This flow manages the complete laboratory testing process from
+# order creation through result reporting.
+# """
+#
+# process_class = LabOrderProcess
+#
+# # Flow definition
+# start = (
+# flow_func(this.start_lab_order)
+# .Next(this.create_order)
+# )
+#
+# create_order = (
+# flow_view(LabOrderCreationView)
+# .Permission('laboratory.can_create_orders')
+# .Next(this.schedule_collection)
+# )
+#
+# schedule_collection = (
+# flow_func(this.schedule_specimen_collection)
+# .Next(this.collect_specimen)
+# )
+#
+# collect_specimen = (
+# flow_view(SpecimenCollectionView)
+# .Permission('laboratory.can_collect_specimens')
+# .Next(this.transport_specimen)
+# )
+#
+# transport_specimen = (
+# flow_func(this.handle_specimen_transport)
+# .Next(this.receive_specimen)
+# )
+#
+# receive_specimen = (
+# flow_view(SpecimenReceiptView)
+# .Permission('laboratory.can_receive_specimens')
+# .Next(this.check_specimen_quality)
+# )
+#
+# check_specimen_quality = (
+# flow_func(this.validate_specimen_quality)
+# .Next(this.process_tests)
+# )
+#
+# process_tests = (
+# flow_view(TestProcessingView)
+# .Permission('laboratory.can_process_tests')
+# .Next(this.enter_results)
+# )
+#
+# enter_results = (
+# flow_view(ResultEntryView)
+# .Permission('laboratory.can_enter_results')
+# .Next(this.verify_results)
+# )
+#
+# verify_results = (
+# flow_view(ResultVerificationView)
+# .Permission('laboratory.can_verify_results')
+# .Next(this.check_critical_values)
+# )
+#
+# check_critical_values = (
+# flow_func(this.check_for_critical_values)
+# .Next(this.report_results)
+# )
+#
+# report_results = (
+# flow_view(ResultReportingView)
+# .Permission('laboratory.can_report_results')
+# .Next(this.finalize_order)
+# )
+#
+# finalize_order = (
+# flow_func(this.complete_lab_order)
+# .Next(this.end)
+# )
+#
+# end = flow_func(this.end_lab_order)
+#
+# # Flow functions
+# def start_lab_order(self, activation):
+# """Initialize the lab order process"""
+# process = activation.process
+# lab_order = process.lab_order
+#
+# # Update order status
+# lab_order.status = 'PENDING'
+# lab_order.save()
+#
+# # Send notification to lab staff
+# self.notify_lab_staff(lab_order)
+#
+# def schedule_specimen_collection(self, activation):
+# """Schedule specimen collection based on order priority"""
+# process = activation.process
+# lab_order = process.lab_order
+#
+# # Calculate collection time based on priority
+# if lab_order.priority == 'STAT':
+# collection_time = timezone.now() + timezone.timedelta(minutes=15)
+# elif lab_order.priority == 'URGENT':
+# collection_time = timezone.now() + timezone.timedelta(hours=1)
+# else:
+# collection_time = timezone.now() + timezone.timedelta(hours=4)
+#
+# # Update order with scheduled collection time
+# lab_order.collection_datetime = collection_time
+# lab_order.save()
+#
+# # Notify collection staff
+# self.notify_collection_staff(lab_order)
+#
+# def handle_specimen_transport(self, activation):
+# """Handle specimen transport to laboratory"""
+# process = activation.process
+# lab_order = process.lab_order
+#
+# # Update specimen status to in transit
+# for specimen in lab_order.specimens.all():
+# specimen.status = 'IN_TRANSIT'
+# specimen.save()
+#
+# # Schedule transport based on priority
+# if lab_order.priority in ['STAT', 'URGENT']:
+# # Immediate transport
+# self.notify_transport_team(lab_order, urgent=True)
+# else:
+# # Regular transport schedule
+# self.schedule_regular_transport(lab_order)
+#
+# def validate_specimen_quality(self, activation):
+# """Validate specimen quality and reject if necessary"""
+# process = activation.process
+# lab_order = process.lab_order
+#
+# rejected_specimens = []
+#
+# for specimen in lab_order.specimens.all():
+# if specimen.quality == 'REJECTED':
+# rejected_specimens.append(specimen)
+#
+# # Notify ordering physician of rejection
+# self.notify_specimen_rejection(specimen)
+#
+# # Request new specimen collection
+# self.request_recollection(specimen)
+#
+# if rejected_specimens:
+# # Update order status if specimens rejected
+# lab_order.status = 'SPECIMEN_REJECTED'
+# lab_order.save()
+# else:
+# # Proceed with processing
+# lab_order.status = 'PROCESSING'
+# lab_order.save()
+#
+# process.specimen_received = True
+# process.save()
+#
+# def check_for_critical_values(self, activation):
+# """Check for critical values and alert if found"""
+# process = activation.process
+# lab_order = process.lab_order
+#
+# critical_results = []
+#
+# for result in lab_order.results.all():
+# if self.is_critical_value(result):
+# critical_results.append(result)
+#
+# if critical_results:
+# # Immediate notification for critical values
+# self.notify_critical_values(lab_order, critical_results)
+#
+# # Mark as critical in order
+# lab_order.has_critical_values = True
+# lab_order.save()
+#
+# def complete_lab_order(self, activation):
+# """Finalize the lab order process"""
+# process = activation.process
+# lab_order = process.lab_order
+#
+# # Update order status
+# lab_order.status = 'COMPLETED'
+# lab_order.completed_datetime = timezone.now()
+# lab_order.save()
+#
+# # Mark process as completed
+# process.results_reported = True
+# process.save()
+#
+# # Send completion notifications
+# self.notify_order_completion(lab_order)
+#
+# def end_lab_order(self, activation):
+# """End the lab order workflow"""
+# process = activation.process
+#
+# # Generate order summary report
+# self.generate_order_summary(process.lab_order)
+#
+# # Helper methods
+# def notify_lab_staff(self, lab_order):
+# """Notify laboratory staff of new order"""
+# from django.contrib.auth.models import Group
+#
+# lab_staff = User.objects.filter(
+# groups__name='Laboratory Staff'
+# )
+#
+# for staff in lab_staff:
+# send_mail(
+# subject=f'New Lab Order: {lab_order.order_number}',
+# message=f'New {lab_order.get_priority_display()} lab order for {lab_order.patient.get_full_name()}.',
+# from_email='laboratory@hospital.com',
+# recipient_list=[staff.email],
+# fail_silently=True
+# )
+#
+# def notify_collection_staff(self, lab_order):
+# """Notify specimen collection staff"""
+# collection_staff = User.objects.filter(
+# groups__name='Specimen Collection'
+# )
+#
+# for staff in collection_staff:
+# send_mail(
+# subject=f'Specimen Collection Required: {lab_order.order_number}',
+# message=f'Specimen collection scheduled for {lab_order.collection_datetime}.',
+# from_email='laboratory@hospital.com',
+# recipient_list=[staff.email],
+# fail_silently=True
+# )
+#
+# def notify_transport_team(self, lab_order, urgent=False):
+# """Notify transport team for specimen pickup"""
+# transport_staff = User.objects.filter(
+# groups__name='Transport Team'
+# )
+#
+# priority_text = "URGENT" if urgent else "ROUTINE"
+#
+# for staff in transport_staff:
+# send_mail(
+# subject=f'{priority_text} Transport: {lab_order.order_number}',
+# message=f'Specimen transport required for lab order {lab_order.order_number}.',
+# from_email='transport@hospital.com',
+# recipient_list=[staff.email],
+# fail_silently=True
+# )
+#
+# def schedule_regular_transport(self, lab_order):
+# """Schedule regular transport pickup"""
+# # This would integrate with transport scheduling system
+# pass
+#
+# def notify_specimen_rejection(self, specimen):
+# """Notify ordering physician of specimen rejection"""
+# if specimen.order.ordering_physician and specimen.order.ordering_physician.email:
+# send_mail(
+# subject=f'Specimen Rejected: {specimen.specimen_number}',
+# message=f'Specimen rejected due to: {specimen.rejection_reason}. Please reorder.',
+# from_email='laboratory@hospital.com',
+# recipient_list=[specimen.order.ordering_physician.email],
+# fail_silently=True
+# )
+#
+# def request_recollection(self, specimen):
+# """Request new specimen collection"""
+# # This would trigger a new collection workflow
+# pass
+#
+# def is_critical_value(self, result):
+# """Check if result value is critical"""
+# # This would implement critical value checking logic
+# # based on test-specific critical ranges
+# return False # Placeholder
+#
+# def notify_critical_values(self, lab_order, critical_results):
+# """Notify physicians of critical values immediately"""
+# if lab_order.ordering_physician and lab_order.ordering_physician.email:
+# result_details = "\n".join([
+# f"{result.test.test_name}: {result.result_value} {result.result_unit}"
+# for result in critical_results
+# ])
+#
+# send_mail(
+# subject=f'CRITICAL VALUES: {lab_order.order_number}',
+# message=f'Critical values detected:\n{result_details}',
+# from_email='laboratory@hospital.com',
+# recipient_list=[lab_order.ordering_physician.email],
+# fail_silently=True
+# )
+#
+# def notify_order_completion(self, lab_order):
+# """Notify ordering physician of completed results"""
+# if lab_order.ordering_physician and lab_order.ordering_physician.email:
+# send_mail(
+# subject=f'Lab Results Available: {lab_order.order_number}',
+# message=f'Laboratory results are now available for {lab_order.patient.get_full_name()}.',
+# from_email='laboratory@hospital.com',
+# recipient_list=[lab_order.ordering_physician.email],
+# fail_silently=True
+# )
+#
+# def generate_order_summary(self, lab_order):
+# """Generate lab order summary report"""
+# # This would generate a comprehensive lab order report
+# pass
+#
+#
+# class QualityControlProcess(Process):
+# """
+# Viewflow process model for quality control procedures
+# """
+# qc_batch = CharField(max_length=50, help_text='QC batch identifier')
+#
+# # Process status tracking
+# qc_samples_prepared = models.BooleanField(default=False)
+# qc_tests_run = models.BooleanField(default=False)
+# qc_results_reviewed = models.BooleanField(default=False)
+# qc_approved = models.BooleanField(default=False)
+#
+# class Meta:
+# verbose_name = 'Quality Control Process'
+# verbose_name_plural = 'Quality Control Processes'
+#
+#
+# class QualityControlFlow(Flow):
+# """
+# Laboratory Quality Control Workflow
+#
+# This flow manages quality control procedures for laboratory testing.
+# """
+#
+# process_class = QualityControlProcess
+#
+# # Flow definition
+# start = (
+# flow_func(this.start_qc_process)
+# .Next(this.prepare_qc_samples)
+# )
+#
+# prepare_qc_samples = (
+# flow_view(QCSamplePreparationView)
+# .Permission('laboratory.can_prepare_qc_samples')
+# .Next(this.run_qc_tests)
+# )
+#
+# run_qc_tests = (
+# flow_view(QCTestExecutionView)
+# .Permission('laboratory.can_run_qc_tests')
+# .Next(this.review_qc_results)
+# )
+#
+# review_qc_results = (
+# flow_view(QCResultReviewView)
+# .Permission('laboratory.can_review_qc_results')
+# .Next(this.approve_qc)
+# )
+#
+# approve_qc = (
+# flow_view(QCApprovalView)
+# .Permission('laboratory.can_approve_qc')
+# .Next(this.finalize_qc)
+# )
+#
+# finalize_qc = (
+# flow_func(this.complete_qc_process)
+# .Next(this.end)
+# )
+#
+# end = flow_func(this.end_qc_process)
+#
+# # Flow functions
+# def start_qc_process(self, activation):
+# """Initialize the QC process"""
+# process = activation.process
+#
+# # Notify QC staff
+# self.notify_qc_staff(process.qc_batch)
+#
+# def complete_qc_process(self, activation):
+# """Finalize the QC process"""
+# process = activation.process
+#
+# # Mark QC as approved
+# process.qc_approved = True
+# process.save()
+#
+# # Release patient results if QC passed
+# self.release_patient_results(process.qc_batch)
+#
+# def end_qc_process(self, activation):
+# """End the QC workflow"""
+# process = activation.process
+#
+# # Generate QC summary report
+# self.generate_qc_summary(process.qc_batch)
+#
+# # Helper methods
+# def notify_qc_staff(self, qc_batch):
+# """Notify QC staff of new QC batch"""
+# qc_staff = User.objects.filter(
+# groups__name='Quality Control'
+# )
+#
+# for staff in qc_staff:
+# send_mail(
+# subject=f'QC Batch Ready: {qc_batch}',
+# message=f'Quality control batch {qc_batch} is ready for processing.',
+# from_email='laboratory@hospital.com',
+# recipient_list=[staff.email],
+# fail_silently=True
+# )
+#
+# def release_patient_results(self, qc_batch):
+# """Release patient results after QC approval"""
+# # This would release held patient results
+# pass
+#
+# def generate_qc_summary(self, qc_batch):
+# """Generate QC summary report"""
+# # This would generate a comprehensive QC report
+# pass
+#
+#
+# # Celery tasks for background processing
+# @celery.job
+# def auto_schedule_collection(order_id):
+# """Background task to automatically schedule specimen collection"""
+# try:
+# lab_order = LabOrder.objects.get(id=order_id)
+#
+# # Auto-assign collection staff based on location and availability
+# collection_staff = User.objects.filter(
+# groups__name='Specimen Collection',
+# is_active=True
+# ).first()
+#
+# if collection_staff:
+# # Create collection task
+# # This would integrate with task management system
+# return True
+#
+# return False
+# except LabOrder.DoesNotExist:
+# return False
+#
+#
+# @celery.job
+# def process_batch_results(batch_id):
+# """Background task to process batch of test results"""
+# try:
+# # This would process a batch of results
+# # and perform automated quality checks
+# return True
+# except Exception:
+# return False
+#
+#
+# @celery.job
+# def generate_daily_qc_report():
+# """Background task to generate daily QC report"""
+# try:
+# # This would generate daily QC summary
+# return True
+# except Exception:
+# return False
+#
diff --git a/logs/hospital_management.log b/logs/hospital_management.log
index a86f851d..30ff10a4 100644
--- a/logs/hospital_management.log
+++ b/logs/hospital_management.log
@@ -182694,3 +182694,6911 @@ INFO 2025-09-06 19:06:33,154 basehttp 33886 6203437056 "GET /en/blood-bank/donor
WARNING 2025-09-06 19:06:33,179 log 33886 6203437056 Not Found: /.well-known/appspecific/com.chrome.devtools.json
WARNING 2025-09-06 19:06:33,181 basehttp 33886 6203437056 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
INFO 2025-09-06 19:06:33,226 basehttp 33886 6203437056 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-06 19:07:33,242 basehttp 33886 6203437056 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-06 19:08:33,254 basehttp 33886 6203437056 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-06 19:09:33,261 basehttp 33886 6203437056 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+WARNING 2025-09-06 19:09:59,880 log 33886 6220263424 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+INFO 2025-09-06 19:09:59,887 basehttp 33886 6203437056 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+WARNING 2025-09-06 19:09:59,888 basehttp 33886 6220263424 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+WARNING 2025-09-06 19:09:59,899 log 33886 6203437056 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-06 19:09:59,899 basehttp 33886 6203437056 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-06 19:10:01,883 basehttp 33886 6203437056 "GET /en/blood-bank/donors/34/eligibility/ HTTP/1.1" 200 34004
+WARNING 2025-09-06 19:10:01,906 log 33886 6203437056 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-06 19:10:01,907 basehttp 33886 6203437056 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-06 19:10:01,947 basehttp 33886 6203437056 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+WARNING 2025-09-06 19:10:12,338 log 33886 6203437056 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-06 19:10:12,338 basehttp 33886 6203437056 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+WARNING 2025-09-06 19:10:12,351 log 33886 6203437056 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-06 19:10:12,353 basehttp 33886 6203437056 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-06 19:10:18,495 basehttp 33886 6203437056 "GET /en/blood-bank/donors/create/ HTTP/1.1" 200 33924
+WARNING 2025-09-06 19:10:18,514 log 33886 6203437056 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-06 19:10:18,514 basehttp 33886 6203437056 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-06 19:10:18,564 basehttp 33886 6203437056 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-06 19:11:18,590 basehttp 33886 6203437056 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-06 19:11:31,467 basehttp 33886 6203437056 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+WARNING 2025-09-06 19:11:31,480 log 33886 6203437056 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-06 19:11:31,480 basehttp 33886 6203437056 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+WARNING 2025-09-06 19:11:31,503 log 33886 6203437056 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-06 19:11:31,503 basehttp 33886 6203437056 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+WARNING 2025-09-06 19:11:41,047 log 33886 6203437056 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-06 19:11:41,048 basehttp 33886 6203437056 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-06 19:11:45,501 basehttp 33886 6203437056 "GET /en/blood-bank/requests/ HTTP/1.1" 200 95494
+WARNING 2025-09-06 19:11:45,523 log 33886 6203437056 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-06 19:11:45,523 basehttp 33886 6203437056 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-06 19:11:45,576 basehttp 33886 6203437056 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-06 19:11:56,062 basehttp 33886 6203437056 "GET /en/blood-bank/requests/21/ HTTP/1.1" 200 32303
+WARNING 2025-09-06 19:11:56,083 log 33886 6203437056 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-06 19:11:56,083 basehttp 33886 6203437056 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-06 19:11:56,125 basehttp 33886 6203437056 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-06 19:11:59,419 basehttp 33886 6203437056 "GET /en/blood-bank/requests/21/issue/ HTTP/1.1" 200 44297
+WARNING 2025-09-06 19:11:59,445 log 33886 6203437056 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-06 19:11:59,446 basehttp 33886 6203437056 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-06 19:11:59,488 basehttp 33886 6203437056 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-06 19:12:59,502 basehttp 33886 6203437056 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+WARNING 2025-09-06 19:13:11,618 log 33886 6220263424 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+INFO 2025-09-06 19:13:11,618 basehttp 33886 6203437056 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+WARNING 2025-09-06 19:13:11,619 basehttp 33886 6220263424 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+WARNING 2025-09-06 19:13:11,629 log 33886 6220263424 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-06 19:13:11,629 basehttp 33886 6220263424 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-06 19:13:26,553 basehttp 33886 6220263424 "GET /blood-bank/api/blood-availability/?blood_group=2&component=1 HTTP/1.1" 302 0
+INFO 2025-09-06 19:13:26,565 basehttp 33886 6203437056 "GET /en/blood-bank/api/blood-availability/?blood_group=2&component=1 HTTP/1.1" 200 22
+INFO 2025-09-06 19:13:36,486 basehttp 33886 6203437056 "GET /en/blood-bank/requests/21/issue/ HTTP/1.1" 200 44297
+WARNING 2025-09-06 19:13:36,502 log 33886 6203437056 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-06 19:13:36,502 basehttp 33886 6203437056 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-06 19:13:36,548 basehttp 33886 6203437056 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+WARNING 2025-09-06 19:13:38,899 log 33886 6203437056 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-06 19:13:38,899 basehttp 33886 6203437056 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+WARNING 2025-09-06 19:13:38,909 log 33886 6203437056 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-06 19:13:38,909 basehttp 33886 6203437056 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-06 19:14:11,624 basehttp 33886 6203437056 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-06 19:15:11,630 basehttp 33886 6203437056 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-06 19:15:38,062 basehttp 33886 6203437056 "GET /blood-bank/api/blood-availability/?blood_group=2&component=1 HTTP/1.1" 302 0
+INFO 2025-09-06 19:15:38,074 basehttp 33886 6203437056 "GET /en/blood-bank/api/blood-availability/?blood_group=2&component=1 HTTP/1.1" 200 22
+INFO 2025-09-06 19:15:41,784 basehttp 33886 6203437056 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+WARNING 2025-09-06 19:15:41,786 log 33886 6237089792 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-06 19:15:41,786 basehttp 33886 6237089792 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-06 19:15:41,807 basehttp 33886 6220263424 "GET /en/blood-bank/requests/ HTTP/1.1" 200 95494
+WARNING 2025-09-06 19:15:41,820 log 33886 6220263424 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-06 19:15:41,820 basehttp 33886 6220263424 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+WARNING 2025-09-06 19:15:41,825 log 33886 6220263424 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-06 19:15:41,825 basehttp 33886 6220263424 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-06 19:15:41,853 basehttp 33886 6220263424 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-06 19:16:41,864 basehttp 33886 6220263424 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-06 19:16:41,956 basehttp 33886 6220263424 "GET /en/blood-bank/requests/ HTTP/1.1" 200 95494
+WARNING 2025-09-06 19:16:41,971 log 33886 6220263424 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-06 19:16:41,971 basehttp 33886 6220263424 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-06 19:16:42,040 basehttp 33886 6220263424 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-06 19:16:57,789 basehttp 33886 6220263424 "GET /en/blood-bank/requests/ HTTP/1.1" 200 95494
+INFO 2025-09-06 19:16:57,799 basehttp 33886 6203437056 "GET /static/css/custom.css HTTP/1.1" 200 2063
+INFO 2025-09-06 19:16:57,801 basehttp 33886 6270742528 "GET /static/plugins/datatables.net-bs5/css/dataTables.bootstrap5.min.css HTTP/1.1" 200 15096
+INFO 2025-09-06 19:16:57,801 basehttp 33886 6287568896 "GET /static/plugins/datatables.net-responsive-bs5/css/responsive.bootstrap5.min.css HTTP/1.1" 200 6044
+WARNING 2025-09-06 19:16:57,807 log 33886 6253916160 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-06 19:16:57,807 basehttp 33886 6253916160 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-06 19:16:57,809 basehttp 33886 6220263424 "GET /static/css/vendor.min.css HTTP/1.1" 200 177466
+INFO 2025-09-06 19:16:57,810 basehttp 33886 6270742528 "GET /static/img/user/user-4.jpg HTTP/1.1" 200 5916
+INFO 2025-09-06 19:16:57,810 basehttp 33886 6203437056 "GET /static/js/htmx.min.js HTTP/1.1" 200 50917
+INFO 2025-09-06 19:16:57,813 basehttp 33886 6203437056 "GET /static/plugins/datatables.net-bs5/js/dataTables.bootstrap5.min.js HTTP/1.1" 200 1470
+INFO 2025-09-06 19:16:57,815 basehttp 33886 6220263424 "GET /static/plugins/datatables.net-responsive/js/dataTables.responsive.min.js HTTP/1.1" 200 16086
+INFO 2025-09-06 19:16:57,815 basehttp 33886 6203437056 "GET /static/plugins/datatables.net-responsive-bs5/js/responsive.bootstrap5.min.js HTTP/1.1" 200 1796
+INFO 2025-09-06 19:16:57,818 basehttp 33886 6237089792 "GET /static/css/default/app.min.css HTTP/1.1" 200 893480
+INFO 2025-09-06 19:16:57,818 basehttp 33886 6270742528 "GET /static/plugins/datatables.net/js/dataTables.min.js HTTP/1.1" 200 95735
+INFO 2025-09-06 19:16:57,820 basehttp 33886 6287568896 "GET /static/js/vendor.min.js HTTP/1.1" 200 1091361
+INFO 2025-09-06 19:16:57,820 basehttp 33886 6253916160 "GET /static/js/app.min.js HTTP/1.1" 200 110394
+INFO 2025-09-06 19:16:58,663 basehttp 33886 6287568896 "GET /static/css/default/app.min.css.map HTTP/1.1" 200 1957526
+INFO 2025-09-06 19:16:58,772 basehttp 33886 6287568896 "GET /static/img/theme/default.jpg HTTP/1.1" 200 26964
+INFO 2025-09-06 19:16:58,772 basehttp 33886 6270742528 "GET /static/img/theme/apple.jpg HTTP/1.1" 200 28822
+INFO 2025-09-06 19:16:58,773 basehttp 33886 6253916160 "GET /static/img/theme/transparent.jpg HTTP/1.1" 200 32747
+INFO 2025-09-06 19:16:58,773 basehttp 33886 6203437056 "GET /static/img/theme/facebook.jpg HTTP/1.1" 200 27881
+INFO 2025-09-06 19:16:58,773 basehttp 33886 6237089792 "GET /static/img/theme/material.jpg HTTP/1.1" 200 28774
+INFO 2025-09-06 19:16:58,774 basehttp 33886 6220263424 "GET /static/img/theme/google.jpg HTTP/1.1" 200 86013
+INFO 2025-09-06 19:16:58,779 basehttp 33886 6237089792 "GET /static/img/version/angular1x.jpg HTTP/1.1" 200 22869
+INFO 2025-09-06 19:16:58,780 basehttp 33886 6270742528 "GET /static/img/version/ajax.jpg HTTP/1.1" 200 20223
+INFO 2025-09-06 19:16:58,781 basehttp 33886 6287568896 "GET /static/img/version/html.jpg HTTP/1.1" 200 17325
+INFO 2025-09-06 19:16:58,781 basehttp 33886 6220263424 "GET /static/img/version/svelte.jpg HTTP/1.1" 200 25060
+INFO 2025-09-06 19:16:58,781 basehttp 33886 6203437056 "GET /static/img/version/angular10x.jpg HTTP/1.1" 200 24580
+INFO 2025-09-06 19:16:58,783 basehttp 33886 6203437056 "GET /static/img/version/vuejs.jpg HTTP/1.1" 200 22518
+INFO 2025-09-06 19:16:58,784 basehttp 33886 6270742528 "GET /static/img/version/django.jpg HTTP/1.1" 200 20935
+INFO 2025-09-06 19:16:58,784 basehttp 33886 6220263424 "GET /static/img/version/laravel.jpg HTTP/1.1" 200 26040
+INFO 2025-09-06 19:16:58,785 basehttp 33886 6253916160 "GET /static/webfonts/fa-solid-900.woff2 HTTP/1.1" 200 158220
+INFO 2025-09-06 19:16:58,785 basehttp 33886 6287568896 "GET /static/img/version/reactjs.jpg HTTP/1.1" 200 26850
+INFO 2025-09-06 19:16:58,786 basehttp 33886 6237089792 "GET /static/img/version/dotnet.jpg HTTP/1.1" 200 24791
+INFO 2025-09-06 19:16:58,788 basehttp 33886 6237089792 "GET /static/img/theme/forum.jpg HTTP/1.1" 200 28744
+INFO 2025-09-06 19:16:58,789 basehttp 33886 6270742528 "GET /static/img/theme/one-page-parallax.jpg HTTP/1.1" 200 22474
+INFO 2025-09-06 19:16:58,789 basehttp 33886 6220263424 "GET /static/img/version/nextjs.jpg HTTP/1.1" 200 20152
+INFO 2025-09-06 19:16:58,789 basehttp 33886 6253916160 "GET /static/img/theme/e-commerce.jpg HTTP/1.1" 200 37734
+INFO 2025-09-06 19:16:58,790 basehttp 33886 6287568896 "GET /static/img/theme/blog.jpg HTTP/1.1" 200 32334
+INFO 2025-09-06 19:16:58,791 basehttp 33886 6237089792 "GET /static/img/theme/corporate.jpg HTTP/1.1" 200 38911
+INFO 2025-09-06 19:16:58,793 basehttp 33886 6203437056 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+WARNING 2025-09-06 19:16:59,723 log 33886 6203437056 Not Found: /favicon.ico
+WARNING 2025-09-06 19:16:59,724 basehttp 33886 6203437056 "GET /favicon.ico HTTP/1.1" 404 2557
+INFO 2025-09-06 19:17:37,138 basehttp 33886 6203437056 "GET /en/blood-bank/requests/ HTTP/1.1" 200 95494
+WARNING 2025-09-06 19:17:37,154 log 33886 6203437056 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-06 19:17:37,154 basehttp 33886 6203437056 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-06 19:17:37,243 basehttp 33886 6203437056 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-06 19:18:37,263 basehttp 33886 6203437056 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-06 19:18:37,321 basehttp 33886 6203437056 "GET /en/blood-bank/requests/ HTTP/1.1" 200 95604
+WARNING 2025-09-06 19:18:37,335 log 33886 6203437056 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-06 19:18:37,335 basehttp 33886 6203437056 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-06 19:18:37,388 basehttp 33886 6203437056 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-06 19:19:37,405 basehttp 33886 6203437056 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-06 19:19:37,469 basehttp 33886 6203437056 "GET /en/blood-bank/requests/ HTTP/1.1" 200 95604
+WARNING 2025-09-06 19:19:37,484 log 33886 6203437056 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-06 19:19:37,484 basehttp 33886 6203437056 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-06 19:19:37,539 basehttp 33886 6203437056 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-06 19:20:33,296 basehttp 33886 6203437056 "GET /en/blood-bank/requests/ HTTP/1.1" 200 95604
+WARNING 2025-09-06 19:20:33,311 log 33886 6203437056 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-06 19:20:33,311 basehttp 33886 6203437056 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-06 19:20:33,370 basehttp 33886 6203437056 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-06 19:21:33,375 basehttp 33886 6203437056 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-06 19:21:33,443 basehttp 33886 6203437056 "GET /en/blood-bank/requests/ HTTP/1.1" 200 95604
+WARNING 2025-09-06 19:21:33,455 log 33886 6203437056 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-06 19:21:33,455 basehttp 33886 6203437056 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-06 19:21:33,507 basehttp 33886 6203437056 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-06 19:21:39,147 basehttp 33886 6203437056 "GET /en/blood-bank/requests/ HTTP/1.1" 200 95604
+WARNING 2025-09-06 19:21:39,161 log 33886 6203437056 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-06 19:21:39,162 basehttp 33886 6203437056 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-06 19:21:39,213 basehttp 33886 6203437056 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-06 19:22:39,221 basehttp 33886 6203437056 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-06 19:22:39,288 basehttp 33886 6203437056 "GET /en/blood-bank/requests/ HTTP/1.1" 200 95604
+WARNING 2025-09-06 19:22:39,308 log 33886 6203437056 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-06 19:22:39,308 basehttp 33886 6203437056 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-06 19:22:39,362 basehttp 33886 6203437056 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-06 19:23:39,371 basehttp 33886 6203437056 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-06 19:23:39,446 basehttp 33886 6203437056 "GET /en/blood-bank/requests/ HTTP/1.1" 200 95604
+WARNING 2025-09-06 19:23:39,464 log 33886 6203437056 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-06 19:23:39,464 basehttp 33886 6203437056 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-06 19:23:39,517 basehttp 33886 6203437056 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-06 19:24:39,535 basehttp 33886 6203437056 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-06 19:24:39,590 basehttp 33886 6203437056 "GET /en/blood-bank/requests/ HTTP/1.1" 200 95604
+WARNING 2025-09-06 19:24:39,608 log 33886 6203437056 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-06 19:24:39,608 basehttp 33886 6203437056 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-06 19:24:39,669 basehttp 33886 6203437056 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-06 19:25:16,406 basehttp 33886 6203437056 "GET /en/blood-bank/requests/31/issue/ HTTP/1.1" 200 44569
+INFO 2025-09-06 19:25:16,420 basehttp 33886 6220263424 "GET /static/plugins/select2/dist/css/select2.min.css HTTP/1.1" 200 14966
+INFO 2025-09-06 19:25:16,422 basehttp 33886 6220263424 "GET /static/plugins/select2/dist/js/select2.min.js HTTP/1.1" 200 70851
+WARNING 2025-09-06 19:25:16,424 log 33886 6203437056 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-06 19:25:16,424 basehttp 33886 6203437056 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-06 19:25:16,476 basehttp 33886 6203437056 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+WARNING 2025-09-06 19:25:29,649 log 33886 6203437056 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-06 19:25:29,650 basehttp 33886 6203437056 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+WARNING 2025-09-06 19:25:29,676 log 33886 6203437056 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-06 19:25:29,676 basehttp 33886 6203437056 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-06 19:25:39,675 basehttp 33886 6203437056 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-06 19:25:39,747 basehttp 33886 6203437056 "GET /en/blood-bank/requests/ HTTP/1.1" 200 95604
+WARNING 2025-09-06 19:25:39,767 log 33886 6203437056 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-06 19:25:39,767 basehttp 33886 6203437056 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-06 19:25:39,816 basehttp 33886 6203437056 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-06 19:26:39,831 basehttp 33886 6203437056 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-06 19:26:39,887 basehttp 33886 6203437056 "GET /en/blood-bank/requests/ HTTP/1.1" 200 95604
+WARNING 2025-09-06 19:26:39,901 log 33886 6203437056 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-06 19:26:39,901 basehttp 33886 6203437056 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-06 19:26:39,973 basehttp 33886 6203437056 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-06 19:27:04,018 basehttp 33886 6203437056 "GET /en/blood-bank/requests/ HTTP/1.1" 200 95604
+WARNING 2025-09-06 19:27:04,039 log 33886 6203437056 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-06 19:27:04,039 basehttp 33886 6203437056 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-06 19:27:04,088 basehttp 33886 6203437056 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-06 19:27:20,045 basehttp 33886 6203437056 "GET /en/blood-bank/requests/ HTTP/1.1" 200 95604
+WARNING 2025-09-06 19:27:20,067 log 33886 6203437056 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-06 19:27:20,067 basehttp 33886 6203437056 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-06 19:27:20,120 basehttp 33886 6203437056 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-06 19:27:45,754 basehttp 33886 6203437056 "GET /en/blood-bank/requests/ HTTP/1.1" 200 95604
+WARNING 2025-09-06 19:27:45,772 log 33886 6203437056 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-06 19:27:45,772 basehttp 33886 6203437056 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-06 19:27:45,827 basehttp 33886 6203437056 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-06 19:27:53,028 basehttp 33886 6203437056 "GET /en/blood-bank/requests/ HTTP/1.1" 200 95604
+INFO 2025-09-06 19:27:53,037 basehttp 33886 6203437056 "GET /static/css/vendor.min.css HTTP/1.1" 200 177466
+INFO 2025-09-06 19:27:53,042 basehttp 33886 6237089792 "GET /static/css/custom.css HTTP/1.1" 200 2063
+INFO 2025-09-06 19:27:53,043 basehttp 33886 6270742528 "GET /static/plugins/datatables.net-bs5/css/dataTables.bootstrap5.min.css HTTP/1.1" 200 15096
+INFO 2025-09-06 19:27:53,044 basehttp 33886 6287568896 "GET /static/plugins/datatables.net-responsive-bs5/css/responsive.bootstrap5.min.css HTTP/1.1" 200 6044
+INFO 2025-09-06 19:27:53,044 basehttp 33886 6203437056 "GET /static/js/htmx.min.js HTTP/1.1" 200 50917
+INFO 2025-09-06 19:27:53,045 basehttp 33886 6237089792 "GET /static/img/user/user-4.jpg HTTP/1.1" 200 5916
+INFO 2025-09-06 19:27:53,047 basehttp 33886 6237089792 "GET /static/plugins/datatables.net-bs5/js/dataTables.bootstrap5.min.js HTTP/1.1" 200 1470
+WARNING 2025-09-06 19:27:53,052 log 33886 6253916160 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-06 19:27:53,053 basehttp 33886 6253916160 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-06 19:27:53,054 basehttp 33886 6203437056 "GET /static/plugins/datatables.net/js/dataTables.min.js HTTP/1.1" 200 95735
+INFO 2025-09-06 19:27:53,055 basehttp 33886 6237089792 "GET /static/plugins/datatables.net-responsive/js/dataTables.responsive.min.js HTTP/1.1" 200 16086
+INFO 2025-09-06 19:27:53,056 basehttp 33886 6287568896 "GET /static/js/app.min.js HTTP/1.1" 200 110394
+INFO 2025-09-06 19:27:53,057 basehttp 33886 6253916160 "GET /static/plugins/datatables.net-responsive-bs5/js/responsive.bootstrap5.min.js HTTP/1.1" 200 1796
+INFO 2025-09-06 19:27:53,059 basehttp 33886 6220263424 "GET /static/css/default/app.min.css HTTP/1.1" 200 893480
+INFO 2025-09-06 19:27:53,059 basehttp 33886 6270742528 "GET /static/js/vendor.min.js HTTP/1.1" 200 1091361
+INFO 2025-09-06 19:27:53,900 basehttp 33886 6270742528 "GET /static/css/default/app.min.css.map HTTP/1.1" 200 1957526
+INFO 2025-09-06 19:27:53,925 basehttp 33886 6253916160 "GET /static/img/theme/apple.jpg HTTP/1.1" 200 28822
+INFO 2025-09-06 19:27:53,926 basehttp 33886 6220263424 "GET /static/img/theme/transparent.jpg HTTP/1.1" 200 32747
+INFO 2025-09-06 19:27:53,926 basehttp 33886 6237089792 "GET /static/img/theme/facebook.jpg HTTP/1.1" 200 27881
+INFO 2025-09-06 19:27:53,927 basehttp 33886 6270742528 "GET /static/img/theme/default.jpg HTTP/1.1" 200 26964
+INFO 2025-09-06 19:27:53,928 basehttp 33886 6287568896 "GET /static/img/theme/material.jpg HTTP/1.1" 200 28774
+INFO 2025-09-06 19:27:53,929 basehttp 33886 6237089792 "GET /static/img/version/ajax.jpg HTTP/1.1" 200 20223
+INFO 2025-09-06 19:27:53,930 basehttp 33886 6203437056 "GET /static/img/theme/google.jpg HTTP/1.1" 200 86013
+INFO 2025-09-06 19:27:53,930 basehttp 33886 6220263424 "GET /static/img/version/html.jpg HTTP/1.1" 200 17325
+INFO 2025-09-06 19:27:53,932 basehttp 33886 6237089792 "GET /static/img/version/django.jpg HTTP/1.1" 200 20935
+INFO 2025-09-06 19:27:53,932 basehttp 33886 6287568896 "GET /static/img/version/angular1x.jpg HTTP/1.1" 200 22869
+INFO 2025-09-06 19:27:53,932 basehttp 33886 6203437056 "GET /static/img/version/laravel.jpg HTTP/1.1" 200 26040
+INFO 2025-09-06 19:27:53,933 basehttp 33886 6270742528 "GET /static/img/version/angular10x.jpg HTTP/1.1" 200 24580
+INFO 2025-09-06 19:27:53,934 basehttp 33886 6220263424 "GET /static/img/version/svelte.jpg HTTP/1.1" 200 25060
+INFO 2025-09-06 19:27:53,936 basehttp 33886 6203437056 "GET /static/img/version/dotnet.jpg HTTP/1.1" 200 24791
+INFO 2025-09-06 19:27:53,936 basehttp 33886 6287568896 "GET /static/img/version/vuejs.jpg HTTP/1.1" 200 22518
+INFO 2025-09-06 19:27:53,937 basehttp 33886 6270742528 "GET /static/img/version/nextjs.jpg HTTP/1.1" 200 20152
+INFO 2025-09-06 19:27:53,937 basehttp 33886 6253916160 "GET /static/webfonts/fa-solid-900.woff2 HTTP/1.1" 200 158220
+INFO 2025-09-06 19:27:53,938 basehttp 33886 6237089792 "GET /static/img/version/reactjs.jpg HTTP/1.1" 200 26850
+INFO 2025-09-06 19:27:53,938 basehttp 33886 6220263424 "GET /static/img/theme/one-page-parallax.jpg HTTP/1.1" 200 22474
+INFO 2025-09-06 19:27:53,945 basehttp 33886 6270742528 "GET /static/img/theme/corporate.jpg HTTP/1.1" 200 38911
+INFO 2025-09-06 19:27:53,956 basehttp 33886 6287568896 "GET /static/img/theme/blog.jpg HTTP/1.1" 200 32334
+INFO 2025-09-06 19:27:53,956 basehttp 33886 6203437056 "GET /static/img/theme/e-commerce.jpg HTTP/1.1" 200 37734
+INFO 2025-09-06 19:27:53,957 basehttp 33886 6253916160 "GET /static/img/theme/forum.jpg HTTP/1.1" 200 28744
+INFO 2025-09-06 19:27:53,962 basehttp 33886 6220263424 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+WARNING 2025-09-06 19:27:54,851 log 33886 6220263424 Not Found: /favicon.ico
+WARNING 2025-09-06 19:27:54,851 basehttp 33886 6220263424 "GET /favicon.ico HTTP/1.1" 404 2557
+INFO 2025-09-06 19:28:36,420 basehttp 33886 6220263424 "GET /en/blood-bank/requests/ HTTP/1.1" 200 95604
+WARNING 2025-09-06 19:28:36,438 log 33886 6220263424 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-06 19:28:36,438 basehttp 33886 6220263424 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-06 19:28:36,519 basehttp 33886 6220263424 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-06 19:28:41,333 basehttp 33886 6220263424 "GET /en/blood-bank/requests/ HTTP/1.1" 200 95604
+INFO 2025-09-06 19:28:41,340 basehttp 33886 6220263424 "GET /static/css/vendor.min.css HTTP/1.1" 200 177466
+INFO 2025-09-06 19:28:41,346 basehttp 33886 6270742528 "GET /static/plugins/datatables.net-responsive-bs5/css/responsive.bootstrap5.min.css HTTP/1.1" 200 6044
+INFO 2025-09-06 19:28:41,347 basehttp 33886 6203437056 "GET /static/css/custom.css HTTP/1.1" 200 2063
+INFO 2025-09-06 19:28:41,347 basehttp 33886 6220263424 "GET /static/plugins/datatables.net-bs5/css/dataTables.bootstrap5.min.css HTTP/1.1" 200 15096
+INFO 2025-09-06 19:28:41,350 basehttp 33886 6237089792 "GET /static/js/htmx.min.js HTTP/1.1" 200 50917
+INFO 2025-09-06 19:28:41,350 basehttp 33886 6203437056 "GET /static/img/user/user-4.jpg HTTP/1.1" 200 5916
+INFO 2025-09-06 19:28:41,355 basehttp 33886 6203437056 "GET /static/plugins/datatables.net-bs5/js/dataTables.bootstrap5.min.js HTTP/1.1" 200 1470
+INFO 2025-09-06 19:28:41,357 basehttp 33886 6220263424 "GET /static/js/app.min.js HTTP/1.1" 200 110394
+INFO 2025-09-06 19:28:41,358 basehttp 33886 6203437056 "GET /static/plugins/datatables.net-responsive/js/dataTables.responsive.min.js HTTP/1.1" 200 16086
+WARNING 2025-09-06 19:28:41,359 log 33886 6287568896 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-06 19:28:41,359 basehttp 33886 6287568896 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-06 19:28:41,360 basehttp 33886 6220263424 "GET /static/plugins/datatables.net-responsive-bs5/js/responsive.bootstrap5.min.js HTTP/1.1" 200 1796
+INFO 2025-09-06 19:28:41,360 basehttp 33886 6237089792 "GET /static/plugins/datatables.net/js/dataTables.min.js HTTP/1.1" 200 95735
+INFO 2025-09-06 19:28:41,363 basehttp 33886 6253916160 "GET /static/css/default/app.min.css HTTP/1.1" 200 893480
+INFO 2025-09-06 19:28:41,363 basehttp 33886 6270742528 "GET /static/js/vendor.min.js HTTP/1.1" 200 1091361
+INFO 2025-09-06 19:28:41,553 basehttp 33886 6270742528 "GET /static/css/default/app.min.css.map HTTP/1.1" 200 1957526
+INFO 2025-09-06 19:28:41,578 basehttp 33886 6253916160 "GET /static/img/theme/transparent.jpg HTTP/1.1" 200 32747
+INFO 2025-09-06 19:28:41,579 basehttp 33886 6237089792 "GET /static/img/theme/apple.jpg HTTP/1.1" 200 28822
+INFO 2025-09-06 19:28:41,579 basehttp 33886 6270742528 "GET /static/img/theme/default.jpg HTTP/1.1" 200 26964
+INFO 2025-09-06 19:28:41,579 basehttp 33886 6220263424 "GET /static/img/theme/material.jpg HTTP/1.1" 200 28774
+INFO 2025-09-06 19:28:41,579 basehttp 33886 6287568896 "GET /static/img/theme/facebook.jpg HTTP/1.1" 200 27881
+INFO 2025-09-06 19:28:41,580 basehttp 33886 6203437056 "GET /static/img/theme/google.jpg HTTP/1.1" 200 86013
+INFO 2025-09-06 19:28:41,583 basehttp 33886 6220263424 "GET /static/img/version/html.jpg HTTP/1.1" 200 17325
+INFO 2025-09-06 19:28:41,584 basehttp 33886 6270742528 "GET /static/img/version/angular1x.jpg HTTP/1.1" 200 22869
+INFO 2025-09-06 19:28:41,584 basehttp 33886 6237089792 "GET /static/img/version/ajax.jpg HTTP/1.1" 200 20223
+INFO 2025-09-06 19:28:41,585 basehttp 33886 6253916160 "GET /static/img/version/angular10x.jpg HTTP/1.1" 200 24580
+INFO 2025-09-06 19:28:41,586 basehttp 33886 6203437056 "GET /static/img/version/svelte.jpg HTTP/1.1" 200 25060
+INFO 2025-09-06 19:28:41,588 basehttp 33886 6270742528 "GET /static/img/version/django.jpg HTTP/1.1" 200 20935
+INFO 2025-09-06 19:28:41,597 basehttp 33886 6270742528 "GET /static/img/version/nextjs.jpg HTTP/1.1" 200 20152
+INFO 2025-09-06 19:28:41,598 basehttp 33886 6237089792 "GET /static/img/version/vuejs.jpg HTTP/1.1" 200 22518
+INFO 2025-09-06 19:28:41,592 basehttp 33886 6253916160 "GET /static/img/version/reactjs.jpg HTTP/1.1" 200 26850
+INFO 2025-09-06 19:28:41,595 basehttp 33886 6220263424 "GET /static/img/version/laravel.jpg HTTP/1.1" 200 26040
+INFO 2025-09-06 19:28:41,604 basehttp 33886 6287568896 "GET /static/webfonts/fa-solid-900.woff2 HTTP/1.1" 200 158220
+INFO 2025-09-06 19:28:41,596 basehttp 33886 6203437056 "GET /static/img/version/dotnet.jpg HTTP/1.1" 200 24791
+INFO 2025-09-06 19:28:41,608 basehttp 33886 6287568896 "GET /static/img/theme/one-page-parallax.jpg HTTP/1.1" 200 22474
+INFO 2025-09-06 19:28:41,608 basehttp 33886 6220263424 "GET /static/img/theme/forum.jpg HTTP/1.1" 200 28744
+INFO 2025-09-06 19:28:41,608 basehttp 33886 6270742528 "GET /static/img/theme/e-commerce.jpg HTTP/1.1" 200 37734
+INFO 2025-09-06 19:28:41,609 basehttp 33886 6237089792 "GET /static/img/theme/corporate.jpg HTTP/1.1" 200 38911
+INFO 2025-09-06 19:28:41,609 basehttp 33886 6203437056 "GET /static/img/theme/blog.jpg HTTP/1.1" 200 32334
+INFO 2025-09-06 19:28:41,612 basehttp 33886 6253916160 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+WARNING 2025-09-06 19:28:41,707 log 33886 6253916160 Not Found: /favicon.ico
+WARNING 2025-09-06 19:28:41,707 basehttp 33886 6253916160 "GET /favicon.ico HTTP/1.1" 404 2557
+INFO 2025-09-06 19:28:43,985 basehttp 33886 6253916160 "GET /en/blood-bank/requests/39/ HTTP/1.1" 200 32942
+WARNING 2025-09-06 19:28:44,003 log 33886 6253916160 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-06 19:28:44,004 basehttp 33886 6253916160 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-06 19:28:44,073 basehttp 33886 6253916160 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+WARNING 2025-09-06 19:28:46,841 log 33886 6253916160 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-06 19:28:46,842 basehttp 33886 6253916160 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+WARNING 2025-09-06 19:28:46,858 log 33886 6253916160 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-06 19:28:46,859 basehttp 33886 6253916160 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-06 19:28:48,647 basehttp 33886 6253916160 "GET /en/blood-bank/requests/39/ HTTP/1.1" 200 32942
+WARNING 2025-09-06 19:28:48,669 log 33886 6253916160 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-06 19:28:48,669 basehttp 33886 6253916160 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-06 19:28:48,709 basehttp 33886 6253916160 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+WARNING 2025-09-06 19:28:50,535 log 33886 6253916160 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-06 19:28:50,535 basehttp 33886 6253916160 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+WARNING 2025-09-06 19:28:50,547 log 33886 6253916160 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-06 19:28:50,547 basehttp 33886 6253916160 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-06 19:28:52,138 basehttp 33886 6253916160 "GET /en/blood-bank/requests/38/issue/ HTTP/1.1" 200 44569
+INFO 2025-09-06 19:28:52,150 basehttp 33886 6253916160 "GET /static/plugins/select2/dist/css/select2.min.css HTTP/1.1" 200 14966
+INFO 2025-09-06 19:28:52,150 basehttp 33886 6203437056 "GET /static/plugins/select2/dist/js/select2.min.js HTTP/1.1" 200 70851
+WARNING 2025-09-06 19:28:52,155 log 33886 6237089792 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-06 19:28:52,155 basehttp 33886 6237089792 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-06 19:28:52,206 basehttp 33886 6237089792 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+WARNING 2025-09-06 19:28:54,000 log 33886 6237089792 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-06 19:28:54,000 basehttp 33886 6237089792 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+WARNING 2025-09-06 19:28:54,010 log 33886 6237089792 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-06 19:28:54,010 basehttp 33886 6237089792 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-06 19:28:56,856 basehttp 33886 6237089792 "GET /en/blood-bank/requests/37/issue/ HTTP/1.1" 200 44297
+WARNING 2025-09-06 19:28:56,876 log 33886 6237089792 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-06 19:28:56,877 basehttp 33886 6237089792 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-06 19:28:56,923 basehttp 33886 6237089792 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+WARNING 2025-09-06 19:29:04,827 log 33886 6237089792 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-06 19:29:04,828 basehttp 33886 6237089792 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+WARNING 2025-09-06 19:29:04,841 log 33886 6237089792 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-06 19:29:04,841 basehttp 33886 6237089792 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-06 19:29:09,836 basehttp 33886 6237089792 "GET /en/blood-bank/requests/?page=2 HTTP/1.1" 200 70207
+WARNING 2025-09-06 19:29:09,853 log 33886 6237089792 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-06 19:29:09,853 basehttp 33886 6237089792 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-06 19:29:09,881 basehttp 33886 6237089792 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-06 19:29:12,237 basehttp 33886 6237089792 "GET /en/blood-bank/requests/?page=1 HTTP/1.1" 200 95604
+WARNING 2025-09-06 19:29:12,259 log 33886 6237089792 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-06 19:29:12,259 basehttp 33886 6237089792 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-06 19:29:12,305 basehttp 33886 6237089792 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-06 19:30:12,315 basehttp 33886 6237089792 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-06 19:30:12,389 basehttp 33886 6237089792 "GET /en/blood-bank/requests/?page=1 HTTP/1.1" 200 95604
+WARNING 2025-09-06 19:30:12,402 log 33886 6237089792 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-06 19:30:12,402 basehttp 33886 6237089792 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-06 19:30:12,449 basehttp 33886 6237089792 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-06 19:31:05,224 autoreload 33886 8747049152 /Users/marwanalwali/manus_project/hospital_management_system_v4/blood_bank/views.py changed, reloading.
+INFO 2025-09-06 19:31:05,721 autoreload 58836 8747049152 Watching for file changes with StatReloader
+INFO 2025-09-06 19:31:12,538 basehttp 58836 6157119488 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-06 19:31:12,555 basehttp 58836 6173945856 "GET /en/blood-bank/requests/?page=1 HTTP/1.1" 200 95604
+WARNING 2025-09-06 19:31:12,568 log 58836 6173945856 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-06 19:31:12,568 basehttp 58836 6173945856 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-06 19:31:12,623 basehttp 58836 6173945856 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-06 19:32:12,642 basehttp 58836 6173945856 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-06 19:32:12,696 basehttp 58836 6173945856 "GET /en/blood-bank/requests/?page=1 HTTP/1.1" 200 95604
+WARNING 2025-09-06 19:32:12,710 log 58836 6173945856 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-06 19:32:12,710 basehttp 58836 6173945856 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-06 19:32:12,762 basehttp 58836 6173945856 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-06 19:32:49,006 autoreload 58836 8747049152 /Users/marwanalwali/manus_project/hospital_management_system_v4/blood_bank/views.py changed, reloading.
+INFO 2025-09-06 19:32:49,342 autoreload 59644 8747049152 Watching for file changes with StatReloader
+INFO 2025-09-06 19:33:26,538 autoreload 59644 8747049152 /Users/marwanalwali/manus_project/hospital_management_system_v4/blood_bank/views.py changed, reloading.
+INFO 2025-09-06 19:33:26,855 autoreload 59959 8747049152 Watching for file changes with StatReloader
+INFO 2025-09-06 19:34:36,707 autoreload 59959 8747049152 /Users/marwanalwali/manus_project/hospital_management_system_v4/blood_bank/views.py changed, reloading.
+INFO 2025-09-06 19:34:37,017 autoreload 60430 8747049152 Watching for file changes with StatReloader
+INFO 2025-09-06 19:37:51,202 autoreload 60430 8747049152 /Users/marwanalwali/manus_project/hospital_management_system_v4/blood_bank/views.py changed, reloading.
+INFO 2025-09-06 19:37:51,504 autoreload 61907 8747049152 Watching for file changes with StatReloader
+INFO 2025-09-06 19:40:12,981 autoreload 61907 8747049152 /Users/marwanalwali/manus_project/hospital_management_system_v4/blood_bank/urls.py changed, reloading.
+INFO 2025-09-06 19:40:13,258 autoreload 62923 8747049152 Watching for file changes with StatReloader
+WARNING 2025-09-06 19:40:24,226 log 62923 6159593472 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-06 19:40:24,226 basehttp 62923 6159593472 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-06 19:40:24,350 basehttp 62923 6159593472 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-06 19:40:25,120 basehttp 62923 6159593472 "GET /en/blood-bank/requests/?page=2 HTTP/1.1" 200 69125
+WARNING 2025-09-06 19:40:25,140 log 62923 6159593472 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-06 19:40:25,140 basehttp 62923 6159593472 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-06 19:40:25,221 basehttp 62923 6159593472 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-06 19:41:10,879 basehttp 62923 6159593472 "GET /en/blood-bank/requests/?page=2 HTTP/1.1" 200 69125
+WARNING 2025-09-06 19:41:10,895 log 62923 6159593472 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-06 19:41:10,895 basehttp 62923 6159593472 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-06 19:41:10,947 basehttp 62923 6159593472 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-06 19:41:41,734 basehttp 62923 6159593472 "GET /en/blood-bank/requests/?page=2 HTTP/1.1" 200 69125
+INFO 2025-09-06 19:41:41,749 basehttp 62923 6226898944 "GET /static/plugins/datatables.net-responsive-bs5/css/responsive.bootstrap5.min.css HTTP/1.1" 200 6044
+INFO 2025-09-06 19:41:41,750 basehttp 62923 6193246208 "GET /static/css/custom.css HTTP/1.1" 200 2063
+INFO 2025-09-06 19:41:41,752 basehttp 62923 6210072576 "GET /static/plugins/datatables.net-bs5/css/dataTables.bootstrap5.min.css HTTP/1.1" 200 15096
+INFO 2025-09-06 19:41:41,753 basehttp 62923 6193246208 "GET /static/img/user/user-4.jpg HTTP/1.1" 200 5916
+INFO 2025-09-06 19:41:41,756 basehttp 62923 6243725312 "GET /static/js/htmx.min.js HTTP/1.1" 200 50917
+INFO 2025-09-06 19:41:41,758 basehttp 62923 6159593472 "GET /static/css/vendor.min.css HTTP/1.1" 200 177466
+WARNING 2025-09-06 19:41:41,760 log 62923 6226898944 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-06 19:41:41,761 basehttp 62923 6226898944 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-06 19:41:41,761 basehttp 62923 6159593472 "GET /static/plugins/datatables.net-bs5/js/dataTables.bootstrap5.min.js HTTP/1.1" 200 1470
+INFO 2025-09-06 19:41:41,765 basehttp 62923 6159593472 "GET /static/plugins/datatables.net-responsive-bs5/js/responsive.bootstrap5.min.js HTTP/1.1" 200 1796
+INFO 2025-09-06 19:41:41,766 basehttp 62923 6226898944 "GET /static/plugins/datatables.net-responsive/js/dataTables.responsive.min.js HTTP/1.1" 200 16086
+INFO 2025-09-06 19:41:41,775 basehttp 62923 6193246208 "GET /static/js/app.min.js HTTP/1.1" 200 110394
+INFO 2025-09-06 19:41:41,786 basehttp 62923 6243725312 "GET /static/plugins/datatables.net/js/dataTables.min.js HTTP/1.1" 200 95735
+INFO 2025-09-06 19:41:41,787 basehttp 62923 6176419840 "GET /static/css/default/app.min.css HTTP/1.1" 200 893480
+INFO 2025-09-06 19:41:41,788 basehttp 62923 6210072576 "GET /static/js/vendor.min.js HTTP/1.1" 200 1091361
+INFO 2025-09-06 19:41:42,607 basehttp 62923 6210072576 "GET /static/css/default/app.min.css.map HTTP/1.1" 200 1957526
+INFO 2025-09-06 19:41:42,627 basehttp 62923 6210072576 "GET /static/img/theme/default.jpg HTTP/1.1" 200 26964
+INFO 2025-09-06 19:41:42,629 basehttp 62923 6193246208 "GET /static/img/theme/facebook.jpg HTTP/1.1" 200 27881
+INFO 2025-09-06 19:41:42,629 basehttp 62923 6176419840 "GET /static/img/theme/transparent.jpg HTTP/1.1" 200 32747
+INFO 2025-09-06 19:41:42,629 basehttp 62923 6243725312 "GET /static/img/theme/apple.jpg HTTP/1.1" 200 28822
+INFO 2025-09-06 19:41:42,629 basehttp 62923 6226898944 "GET /static/img/theme/material.jpg HTTP/1.1" 200 28774
+INFO 2025-09-06 19:41:42,637 basehttp 62923 6193246208 "GET /static/img/version/html.jpg HTTP/1.1" 200 17325
+INFO 2025-09-06 19:41:42,653 basehttp 62923 6226898944 "GET /static/img/version/angular1x.jpg HTTP/1.1" 200 22869
+INFO 2025-09-06 19:41:42,654 basehttp 62923 6243725312 "GET /static/img/version/angular10x.jpg HTTP/1.1" 200 24580
+INFO 2025-09-06 19:41:42,654 basehttp 62923 6159593472 "GET /static/img/theme/google.jpg HTTP/1.1" 200 86013
+INFO 2025-09-06 19:41:42,655 basehttp 62923 6193246208 "GET /static/img/version/svelte.jpg HTTP/1.1" 200 25060
+INFO 2025-09-06 19:41:42,655 basehttp 62923 6176419840 "GET /static/img/version/ajax.jpg HTTP/1.1" 200 20223
+INFO 2025-09-06 19:41:42,656 basehttp 62923 6159593472 "GET /static/img/version/vuejs.jpg HTTP/1.1" 200 22518
+INFO 2025-09-06 19:41:42,658 basehttp 62923 6226898944 "GET /static/img/version/django.jpg HTTP/1.1" 200 20935
+INFO 2025-09-06 19:41:42,658 basehttp 62923 6176419840 "GET /static/img/version/reactjs.jpg HTTP/1.1" 200 26850
+INFO 2025-09-06 19:41:42,658 basehttp 62923 6243725312 "GET /static/img/version/laravel.jpg HTTP/1.1" 200 26040
+INFO 2025-09-06 19:41:42,658 basehttp 62923 6193246208 "GET /static/img/version/dotnet.jpg HTTP/1.1" 200 24791
+INFO 2025-09-06 19:41:42,660 basehttp 62923 6159593472 "GET /static/img/version/nextjs.jpg HTTP/1.1" 200 20152
+INFO 2025-09-06 19:41:42,660 basehttp 62923 6210072576 "GET /static/webfonts/fa-solid-900.woff2 HTTP/1.1" 200 158220
+INFO 2025-09-06 19:41:42,662 basehttp 62923 6226898944 "GET /static/img/theme/forum.jpg HTTP/1.1" 200 28744
+INFO 2025-09-06 19:41:42,663 basehttp 62923 6176419840 "GET /static/img/theme/blog.jpg HTTP/1.1" 200 32334
+INFO 2025-09-06 19:41:42,664 basehttp 62923 6243725312 "GET /static/img/theme/e-commerce.jpg HTTP/1.1" 200 37734
+INFO 2025-09-06 19:41:42,665 basehttp 62923 6193246208 "GET /static/img/theme/one-page-parallax.jpg HTTP/1.1" 200 22474
+INFO 2025-09-06 19:41:42,665 basehttp 62923 6159593472 "GET /static/img/theme/corporate.jpg HTTP/1.1" 200 38911
+INFO 2025-09-06 19:41:42,684 basehttp 62923 6159593472 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+WARNING 2025-09-06 19:41:43,610 log 62923 6159593472 Not Found: /favicon.ico
+WARNING 2025-09-06 19:41:43,610 basehttp 62923 6159593472 "GET /favicon.ico HTTP/1.1" 404 2557
+INFO 2025-09-06 19:42:07,122 basehttp 62923 6159593472 "GET /en/blood-bank/requests/15/issue/ HTTP/1.1" 200 44297
+INFO 2025-09-06 19:42:07,134 basehttp 62923 6159593472 "GET /static/plugins/select2/dist/css/select2.min.css HTTP/1.1" 200 14966
+INFO 2025-09-06 19:42:07,134 basehttp 62923 6193246208 "GET /static/plugins/select2/dist/js/select2.min.js HTTP/1.1" 200 70851
+WARNING 2025-09-06 19:42:07,138 log 62923 6243725312 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-06 19:42:07,138 basehttp 62923 6243725312 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-06 19:42:07,204 basehttp 62923 6243725312 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-06 19:43:02,125 basehttp 62923 6243725312 "GET /en/blood-bank/requests/15/issue/ HTTP/1.1" 200 44298
+WARNING 2025-09-06 19:43:02,152 log 62923 6243725312 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-06 19:43:02,152 basehttp 62923 6243725312 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-06 19:43:02,191 basehttp 62923 6243725312 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-06 19:43:14,691 basehttp 62923 6243725312 "GET /en/blood-bank/requests/15/issue/ HTTP/1.1" 200 44298
+INFO 2025-09-06 19:43:14,701 basehttp 62923 6159593472 "GET /static/css/custom.css HTTP/1.1" 200 2063
+INFO 2025-09-06 19:43:14,702 basehttp 62923 6210072576 "GET /static/img/user/user-4.jpg HTTP/1.1" 200 5916
+INFO 2025-09-06 19:43:14,703 basehttp 62923 6176419840 "GET /static/plugins/select2/dist/css/select2.min.css HTTP/1.1" 200 14966
+INFO 2025-09-06 19:43:14,708 basehttp 62923 6226898944 "GET /static/js/htmx.min.js HTTP/1.1" 200 50917
+INFO 2025-09-06 19:43:14,710 basehttp 62923 6243725312 "GET /static/css/vendor.min.css HTTP/1.1" 200 177466
+INFO 2025-09-06 19:43:14,711 basehttp 62923 6176419840 "GET /static/js/app.min.js HTTP/1.1" 200 110394
+WARNING 2025-09-06 19:43:14,715 log 62923 6159593472 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-06 19:43:14,715 basehttp 62923 6159593472 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-06 19:43:14,715 basehttp 62923 6226898944 "GET /static/plugins/select2/dist/js/select2.min.js HTTP/1.1" 200 70851
+INFO 2025-09-06 19:43:14,718 basehttp 62923 6193246208 "GET /static/css/default/app.min.css HTTP/1.1" 200 893480
+INFO 2025-09-06 19:43:14,719 basehttp 62923 6210072576 "GET /static/js/vendor.min.js HTTP/1.1" 200 1091361
+INFO 2025-09-06 19:43:14,856 basehttp 62923 6210072576 "GET /static/css/default/app.min.css.map HTTP/1.1" 200 1957526
+INFO 2025-09-06 19:43:14,878 basehttp 62923 6210072576 "GET /static/img/theme/default.jpg HTTP/1.1" 200 26964
+INFO 2025-09-06 19:43:14,879 basehttp 62923 6176419840 "GET /static/img/theme/facebook.jpg HTTP/1.1" 200 27881
+INFO 2025-09-06 19:43:14,879 basehttp 62923 6193246208 "GET /static/img/theme/transparent.jpg HTTP/1.1" 200 32747
+INFO 2025-09-06 19:43:14,880 basehttp 62923 6159593472 "GET /static/img/theme/material.jpg HTTP/1.1" 200 28774
+INFO 2025-09-06 19:43:14,880 basehttp 62923 6226898944 "GET /static/img/theme/apple.jpg HTTP/1.1" 200 28822
+INFO 2025-09-06 19:43:14,882 basehttp 62923 6226898944 "GET /static/img/version/angular10x.jpg HTTP/1.1" 200 24580
+INFO 2025-09-06 19:43:14,882 basehttp 62923 6243725312 "GET /static/img/theme/google.jpg HTTP/1.1" 200 86013
+INFO 2025-09-06 19:43:14,882 basehttp 62923 6176419840 "GET /static/img/version/angular1x.jpg HTTP/1.1" 200 22869
+INFO 2025-09-06 19:43:14,883 basehttp 62923 6159593472 "GET /static/img/version/ajax.jpg HTTP/1.1" 200 20223
+INFO 2025-09-06 19:43:14,883 basehttp 62923 6193246208 "GET /static/img/version/html.jpg HTTP/1.1" 200 17325
+INFO 2025-09-06 19:43:14,886 basehttp 62923 6243725312 "GET /static/img/version/svelte.jpg HTTP/1.1" 200 25060
+INFO 2025-09-06 19:43:14,886 basehttp 62923 6176419840 "GET /static/img/version/django.jpg HTTP/1.1" 200 20935
+INFO 2025-09-06 19:43:14,886 basehttp 62923 6193246208 "GET /static/img/version/vuejs.jpg HTTP/1.1" 200 22518
+INFO 2025-09-06 19:43:14,887 basehttp 62923 6226898944 "GET /static/img/version/laravel.jpg HTTP/1.1" 200 26040
+INFO 2025-09-06 19:43:14,887 basehttp 62923 6210072576 "GET /static/webfonts/fa-solid-900.woff2 HTTP/1.1" 200 158220
+INFO 2025-09-06 19:43:14,887 basehttp 62923 6159593472 "GET /static/img/version/reactjs.jpg HTTP/1.1" 200 26850
+INFO 2025-09-06 19:43:14,888 basehttp 62923 6226898944 "GET /static/img/version/dotnet.jpg HTTP/1.1" 200 24791
+INFO 2025-09-06 19:43:14,889 basehttp 62923 6159593472 "GET /static/img/version/nextjs.jpg HTTP/1.1" 200 20152
+INFO 2025-09-06 19:43:14,889 basehttp 62923 6210072576 "GET /static/img/theme/one-page-parallax.jpg HTTP/1.1" 200 22474
+INFO 2025-09-06 19:43:14,890 basehttp 62923 6226898944 "GET /static/img/theme/e-commerce.jpg HTTP/1.1" 200 37734
+INFO 2025-09-06 19:43:14,891 basehttp 62923 6176419840 "GET /static/img/theme/blog.jpg HTTP/1.1" 200 32334
+INFO 2025-09-06 19:43:14,891 basehttp 62923 6210072576 "GET /static/img/theme/corporate.jpg HTTP/1.1" 200 38911
+INFO 2025-09-06 19:43:14,892 basehttp 62923 6193246208 "GET /static/img/theme/forum.jpg HTTP/1.1" 200 28744
+INFO 2025-09-06 19:43:14,894 basehttp 62923 6243725312 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+WARNING 2025-09-06 19:43:14,998 log 62923 6243725312 Not Found: /favicon.ico
+WARNING 2025-09-06 19:43:14,998 basehttp 62923 6243725312 "GET /favicon.ico HTTP/1.1" 404 2557
+INFO 2025-09-06 19:43:26,976 basehttp 62923 6243725312 "GET /en/blood-bank/requests/?page=2 HTTP/1.1" 200 69125
+INFO 2025-09-06 19:43:26,992 basehttp 62923 6193246208 "GET /static/plugins/datatables.net-responsive-bs5/css/responsive.bootstrap5.min.css HTTP/1.1" 200 6044
+INFO 2025-09-06 19:43:26,992 basehttp 62923 6226898944 "GET /static/plugins/datatables.net-bs5/js/dataTables.bootstrap5.min.js HTTP/1.1" 200 1470
+INFO 2025-09-06 19:43:26,993 basehttp 62923 6243725312 "GET /static/plugins/datatables.net-bs5/css/dataTables.bootstrap5.min.css HTTP/1.1" 200 15096
+INFO 2025-09-06 19:43:26,993 basehttp 62923 6176419840 "GET /static/plugins/datatables.net/js/dataTables.min.js HTTP/1.1" 200 95735
+WARNING 2025-09-06 19:43:26,998 log 62923 6210072576 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-06 19:43:26,998 basehttp 62923 6210072576 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-06 19:43:26,998 basehttp 62923 6176419840 "GET /static/plugins/datatables.net-responsive/js/dataTables.responsive.min.js HTTP/1.1" 200 16086
+INFO 2025-09-06 19:43:26,998 basehttp 62923 6243725312 "GET /static/plugins/datatables.net-responsive-bs5/js/responsive.bootstrap5.min.js HTTP/1.1" 200 1796
+INFO 2025-09-06 19:44:27,096 basehttp 62923 6176419840 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-06 19:44:27,147 basehttp 62923 6176419840 "GET /en/blood-bank/requests/?page=2 HTTP/1.1" 200 69125
+WARNING 2025-09-06 19:44:27,161 log 62923 6176419840 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-06 19:44:27,162 basehttp 62923 6176419840 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-06 19:44:27,214 basehttp 62923 6176419840 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-06 19:45:27,226 basehttp 62923 6176419840 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-06 19:45:27,281 basehttp 62923 6176419840 "GET /en/blood-bank/requests/?page=2 HTTP/1.1" 200 69125
+WARNING 2025-09-06 19:45:27,296 log 62923 6176419840 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-06 19:45:27,296 basehttp 62923 6176419840 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-06 19:45:27,348 basehttp 62923 6176419840 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-06 19:46:13,992 basehttp 62923 6176419840 "GET /en/blood-bank/requests/?page=2 HTTP/1.1" 200 69127
+WARNING 2025-09-06 19:46:14,008 log 62923 6176419840 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-06 19:46:14,008 basehttp 62923 6176419840 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-06 19:46:14,061 basehttp 62923 6176419840 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-06 19:47:04,387 basehttp 62923 6176419840 "GET /en/admin/blood_bank/bloodrequest/ HTTP/1.1" 200 113405
+INFO 2025-09-06 19:47:04,399 basehttp 62923 6226898944 "GET /static/admin/css/nav_sidebar.css HTTP/1.1" 200 2810
+INFO 2025-09-06 19:47:04,399 basehttp 62923 6243725312 "GET /static/admin/css/dark_mode.css HTTP/1.1" 200 2808
+INFO 2025-09-06 19:47:04,399 basehttp 62923 6193246208 "GET /static/admin/css/changelists.css HTTP/1.1" 200 6878
+INFO 2025-09-06 19:47:04,399 basehttp 62923 6176419840 "GET /static/admin/css/base.css HTTP/1.1" 200 22120
+INFO 2025-09-06 19:47:04,399 basehttp 62923 6210072576 "GET /static/admin/js/theme.js HTTP/1.1" 200 1653
+INFO 2025-09-06 19:47:04,401 basehttp 62923 6243725312 "GET /static/admin/css/responsive.css HTTP/1.1" 200 16565
+INFO 2025-09-06 19:47:04,402 basehttp 62923 6210072576 "GET /static/admin/js/jquery.init.js HTTP/1.1" 200 347
+INFO 2025-09-06 19:47:04,402 basehttp 62923 6193246208 "GET /static/admin/js/admin/RelatedObjectLookups.js HTTP/1.1" 200 9777
+INFO 2025-09-06 19:47:04,403 basehttp 62923 6176419840 "GET /static/admin/js/core.js HTTP/1.1" 200 6208
+INFO 2025-09-06 19:47:04,405 basehttp 62923 6243725312 "GET /static/admin/js/actions.js HTTP/1.1" 200 8076
+INFO 2025-09-06 19:47:04,405 basehttp 62923 6193246208 "GET /static/admin/js/prepopulate.js HTTP/1.1" 200 1531
+INFO 2025-09-06 19:47:04,406 basehttp 62923 6210072576 "GET /static/admin/js/urlify.js HTTP/1.1" 200 7887
+INFO 2025-09-06 19:47:04,407 basehttp 62923 6159593472 "GET /en/admin/jsi18n/ HTTP/1.1" 200 3342
+INFO 2025-09-06 19:47:04,407 basehttp 62923 6193246208 "GET /static/admin/img/search.svg HTTP/1.1" 200 458
+INFO 2025-09-06 19:47:04,408 basehttp 62923 6226898944 "GET /static/admin/js/vendor/jquery/jquery.js HTTP/1.1" 200 285314
+INFO 2025-09-06 19:47:04,409 basehttp 62923 6176419840 "GET /static/admin/js/vendor/xregexp/xregexp.js HTTP/1.1" 200 325171
+INFO 2025-09-06 19:47:04,412 basehttp 62923 6226898944 "GET /static/admin/js/nav_sidebar.js HTTP/1.1" 200 3063
+INFO 2025-09-06 19:47:04,414 basehttp 62923 6176419840 "GET /static/admin/js/filters.js HTTP/1.1" 200 978
+INFO 2025-09-06 19:47:04,422 basehttp 62923 6176419840 "GET /static/admin/img/icon-addlink.svg HTTP/1.1" 200 331
+INFO 2025-09-06 19:47:04,422 basehttp 62923 6176419840 "GET /static/admin/img/sorting-icons.svg HTTP/1.1" 200 1097
+INFO 2025-09-06 19:47:04,422 basehttp 62923 6226898944 "GET /static/admin/img/tooltag-add.svg HTTP/1.1" 200 331
+INFO 2025-09-06 19:47:04,423 basehttp 62923 6193246208 "GET /static/admin/img/icon-viewlink.svg HTTP/1.1" 200 581
+INFO 2025-09-06 19:47:06,558 basehttp 62923 6193246208 "GET /en/admin/blood_bank/bloodrequest/40/change/ HTTP/1.1" 200 128128
+INFO 2025-09-06 19:47:06,577 basehttp 62923 6193246208 "GET /static/admin/css/forms.css HTTP/1.1" 200 8525
+INFO 2025-09-06 19:47:06,577 basehttp 62923 6243725312 "GET /static/admin/js/prepopulate_init.js HTTP/1.1" 200 586
+INFO 2025-09-06 19:47:06,578 basehttp 62923 6176419840 "GET /static/admin/js/calendar.js HTTP/1.1" 200 9141
+INFO 2025-09-06 19:47:06,578 basehttp 62923 6210072576 "GET /static/admin/js/inlines.js HTTP/1.1" 200 15628
+INFO 2025-09-06 19:47:06,578 basehttp 62923 6159593472 "GET /static/admin/js/admin/DateTimeShortcuts.js HTTP/1.1" 200 19319
+INFO 2025-09-06 19:47:06,578 basehttp 62923 6210072576 "GET /static/admin/css/widgets.css HTTP/1.1" 200 11991
+INFO 2025-09-06 19:47:06,580 basehttp 62923 6210072576 "GET /static/admin/img/icon-changelink.svg HTTP/1.1" 200 380
+INFO 2025-09-06 19:47:06,581 basehttp 62923 6210072576 "GET /static/admin/img/icon-deletelink.svg HTTP/1.1" 200 392
+INFO 2025-09-06 19:47:06,582 basehttp 62923 6226898944 "GET /en/admin/jsi18n/ HTTP/1.1" 200 3342
+INFO 2025-09-06 19:47:06,583 basehttp 62923 6210072576 "GET /static/admin/js/change_form.js HTTP/1.1" 200 606
+INFO 2025-09-06 19:47:06,609 basehttp 62923 6226898944 "GET /static/admin/img/icon-clock.svg HTTP/1.1" 200 677
+INFO 2025-09-06 19:47:06,609 basehttp 62923 6210072576 "GET /static/admin/img/icon-calendar.svg HTTP/1.1" 200 1086
+INFO 2025-09-06 19:47:11,976 basehttp 62923 6210072576 "POST /en/admin/blood_bank/bloodrequest/40/change/ HTTP/1.1" 302 0
+INFO 2025-09-06 19:47:12,013 basehttp 62923 6210072576 "GET /en/admin/blood_bank/bloodrequest/ HTTP/1.1" 200 113680
+INFO 2025-09-06 19:47:12,028 basehttp 62923 6210072576 "GET /en/admin/jsi18n/ HTTP/1.1" 200 3342
+INFO 2025-09-06 19:47:12,036 basehttp 62923 6210072576 "GET /static/admin/img/icon-yes.svg HTTP/1.1" 200 436
+INFO 2025-09-06 19:47:14,103 basehttp 62923 6210072576 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-06 19:47:14,114 basehttp 62923 6226898944 "GET /en/blood-bank/requests/?page=2 HTTP/1.1" 200 69127
+WARNING 2025-09-06 19:47:14,125 log 62923 6226898944 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-06 19:47:14,125 basehttp 62923 6226898944 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-06 19:47:14,175 basehttp 62923 6226898944 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-06 19:48:15,133 basehttp 62923 6226898944 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-06 19:48:15,144 basehttp 62923 6210072576 "GET /en/blood-bank/requests/?page=2 HTTP/1.1" 200 69127
+WARNING 2025-09-06 19:48:15,156 log 62923 6210072576 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-06 19:48:15,157 basehttp 62923 6210072576 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-06 19:48:15,218 basehttp 62923 6210072576 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-06 19:48:37,932 basehttp 62923 6210072576 "GET /en/blood-bank/requests/?page=2 HTTP/1.1" 200 69123
+WARNING 2025-09-06 19:48:37,948 log 62923 6210072576 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-06 19:48:37,948 basehttp 62923 6210072576 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-06 19:48:38,001 basehttp 62923 6210072576 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-06 19:49:23,812 basehttp 62923 6210072576 "GET /en/blood-bank/requests/?page=2 HTTP/1.1" 200 69119
+WARNING 2025-09-06 19:49:23,831 log 62923 6210072576 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-06 19:49:23,831 basehttp 62923 6210072576 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-06 19:49:23,874 basehttp 62923 6210072576 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-06 19:49:37,620 basehttp 62923 6210072576 "GET /en/blood-bank/requests/ HTTP/1.1" 200 94515
+WARNING 2025-09-06 19:49:37,637 log 62923 6210072576 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-06 19:49:37,637 basehttp 62923 6210072576 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-06 19:49:38,885 basehttp 62923 6210072576 "GET /en/blood-bank/ HTTP/1.1" 200 121063
+WARNING 2025-09-06 19:49:38,905 log 62923 6210072576 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-06 19:49:38,905 basehttp 62923 6210072576 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-06 19:49:45,653 basehttp 62923 6210072576 "GET /en/blood-bank/units/ HTTP/1.1" 200 88820
+WARNING 2025-09-06 19:49:45,673 log 62923 6210072576 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-06 19:49:45,673 basehttp 62923 6210072576 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-06 19:49:45,735 basehttp 62923 6210072576 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-06 19:50:53,650 basehttp 62923 6159593472 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-06 19:51:54,644 basehttp 62923 6159593472 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-06 19:52:55,646 basehttp 62923 6159593472 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-06 19:54:25,871 basehttp 62923 6159593472 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-06 19:57:18,309 basehttp 62923 6159593472 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-06 19:58:19,303 basehttp 62923 6159593472 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-06 20:32:39,307 basehttp 62923 6159593472 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+WARNING 2025-09-06 20:43:02,490 log 62923 6193246208 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+INFO 2025-09-06 20:43:02,491 basehttp 62923 6159593472 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+WARNING 2025-09-06 20:43:02,492 basehttp 62923 6193246208 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-06 20:43:02,506 basehttp 62923 6176419840 "GET /en/blood-bank/ HTTP/1.1" 200 121063
+WARNING 2025-09-06 20:43:02,517 log 62923 6176419840 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-06 20:43:02,518 basehttp 62923 6176419840 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+WARNING 2025-09-06 20:43:02,524 log 62923 6176419840 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-06 20:43:02,524 basehttp 62923 6176419840 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-06 20:43:02,594 basehttp 62923 6176419840 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-06 20:43:03,304 basehttp 62923 6176419840 "GET /en/inventory/stock/ HTTP/1.1" 200 134411
+INFO 2025-09-06 20:43:03,318 basehttp 62923 6176419840 "GET /static/plugins/dropzone/src/options.js HTTP/1.1" 200 23721
+WARNING 2025-09-06 20:43:03,321 log 62923 6159593472 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-06 20:43:03,321 basehttp 62923 6159593472 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-06 20:43:04,834 basehttp 62923 6159593472 "GET / HTTP/1.1" 302 0
+INFO 2025-09-06 20:43:04,854 basehttp 62923 6176419840 "GET /en/ HTTP/1.1" 200 49790
+WARNING 2025-09-06 20:43:04,870 log 62923 6176419840 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-06 20:43:04,871 basehttp 62923 6176419840 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-06 20:43:04,922 basehttp 62923 6176419840 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-06 20:43:04,932 basehttp 62923 6210072576 "GET /en/htmx/tenant-info/ HTTP/1.1" 200 1043
+INFO 2025-09-06 20:43:04,935 basehttp 62923 6193246208 "GET /en/htmx/system-health/ HTTP/1.1" 200 1356
+INFO 2025-09-06 20:43:04,948 basehttp 62923 6159593472 "GET /en/htmx/dashboard-stats/ HTTP/1.1" 200 2094
+INFO 2025-09-06 20:43:20,053 basehttp 62923 6159593472 "GET /en/patients/register/ HTTP/1.1" 200 27711
+WARNING 2025-09-06 20:43:20,075 log 62923 6159593472 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-06 20:43:20,075 basehttp 62923 6159593472 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-06 20:43:20,113 basehttp 62923 6159593472 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+WARNING 2025-09-06 20:43:35,146 log 62923 6193246208 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+INFO 2025-09-06 20:43:35,146 basehttp 62923 6159593472 "GET /en/htmx/dashboard-stats/ HTTP/1.1" 200 2094
+WARNING 2025-09-06 20:43:35,146 basehttp 62923 6193246208 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+WARNING 2025-09-06 20:43:35,177 log 62923 6159593472 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-06 20:43:35,182 basehttp 62923 6159593472 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-06 20:43:36,812 basehttp 62923 6159593472 "GET /en/appointments/create/ HTTP/1.1" 200 36462
+WARNING 2025-09-06 20:43:36,833 log 62923 6159593472 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-06 20:43:36,833 basehttp 62923 6159593472 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-06 20:43:36,869 basehttp 62923 6159593472 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+WARNING 2025-09-06 20:43:44,391 log 62923 6159593472 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-06 20:43:44,391 basehttp 62923 6159593472 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+WARNING 2025-09-06 20:43:44,403 log 62923 6159593472 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-06 20:43:44,404 basehttp 62923 6159593472 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-06 20:43:45,956 basehttp 62923 6159593472 "GET /en/ HTTP/1.1" 200 49790
+WARNING 2025-09-06 20:43:45,970 log 62923 6159593472 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-06 20:43:45,970 basehttp 62923 6159593472 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-06 20:43:46,043 basehttp 62923 6159593472 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-06 20:43:46,047 basehttp 62923 6210072576 "GET /en/htmx/system-health/ HTTP/1.1" 200 1356
+INFO 2025-09-06 20:43:46,047 basehttp 62923 6176419840 "GET /en/htmx/tenant-info/ HTTP/1.1" 200 1043
+INFO 2025-09-06 20:43:46,049 basehttp 62923 6193246208 "GET /en/htmx/dashboard-stats/ HTTP/1.1" 200 2094
+INFO 2025-09-06 20:43:51,723 basehttp 62923 6193246208 "GET /en/billing/bills/create/ HTTP/1.1" 200 109266
+WARNING 2025-09-06 20:43:51,746 log 62923 6193246208 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-06 20:43:51,746 basehttp 62923 6193246208 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-06 20:43:51,798 basehttp 62923 6193246208 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-06 20:44:51,815 basehttp 62923 6193246208 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-06 20:45:51,819 basehttp 62923 6193246208 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-06 20:46:51,820 basehttp 62923 6193246208 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-06 20:47:51,813 basehttp 62923 6193246208 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-06 20:48:12,511 basehttp 62923 6193246208 "GET /en/billing/bills/create/ HTTP/1.1" 200 110464
+WARNING 2025-09-06 20:48:12,528 log 62923 6193246208 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-06 20:48:12,529 basehttp 62923 6193246208 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-06 20:48:12,588 basehttp 62923 6193246208 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-06 20:48:33,842 basehttp 62923 6193246208 "GET /en/billing/bills/create/ HTTP/1.1" 200 110432
+WARNING 2025-09-06 20:48:33,859 log 62923 6193246208 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-06 20:48:33,859 basehttp 62923 6193246208 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-06 20:48:33,912 basehttp 62923 6193246208 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-06 20:49:22,973 basehttp 62923 6193246208 "GET /en/billing/bills/ HTTP/1.1" 200 135104
+WARNING 2025-09-06 20:49:22,996 log 62923 6193246208 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-06 20:49:22,996 basehttp 62923 6193246208 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-06 20:49:23,028 basehttp 62923 6193246208 "GET /static/css/saudiriyalsymbol.woff2 HTTP/1.1" 200 720
+INFO 2025-09-06 20:49:23,071 basehttp 62923 6193246208 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-06 20:49:23,076 basehttp 62923 6159593472 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4938
+INFO 2025-09-06 20:50:23,072 basehttp 62923 6159593472 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-06 20:50:23,075 basehttp 62923 6193246208 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4938
+INFO 2025-09-06 20:51:23,085 basehttp 62923 6193246208 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-06 20:51:23,088 basehttp 62923 6159593472 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4938
+INFO 2025-09-06 20:51:33,802 basehttp 62923 6159593472 "GET /en/billing/bills/ HTTP/1.1" 200 101540
+WARNING 2025-09-06 20:51:33,820 log 62923 6159593472 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-06 20:51:33,820 basehttp 62923 6159593472 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-06 20:51:33,880 basehttp 62923 6159593472 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-06 20:51:33,884 basehttp 62923 6193246208 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4938
+ERROR 2025-09-06 20:51:54,500 log 62923 6193246208 Internal Server Error: /en/billing/bills/a668a9c6-ab05-40eb-96f3-5c56e1efc6d9/
+Traceback (most recent call last):
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/core/handlers/exception.py", line 55, in inner
+ response = get_response(request)
+ ^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/core/handlers/base.py", line 220, in _get_response
+ response = response.render()
+ ^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/response.py", line 114, in render
+ self.content = self.rendered_content
+ ^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/response.py", line 92, in rendered_content
+ return template.render(context, self._request)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/backends/django.py", line 107, in render
+ return self.template.render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 171, in render
+ return self._render(context)
+ ^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 163, in _render
+ return self.nodelist.render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 1016, in render
+ return SafeString("".join([node.render_annotated(context) for node in self]))
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 977, in render_annotated
+ return self.render(context)
+ ^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/loader_tags.py", line 159, in render
+ return compiled_parent._render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 163, in _render
+ return self.nodelist.render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 1016, in render
+ return SafeString("".join([node.render_annotated(context) for node in self]))
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 977, in render_annotated
+ return self.render(context)
+ ^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/loader_tags.py", line 65, in render
+ result = block.nodelist.render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 1016, in render
+ return SafeString("".join([node.render_annotated(context) for node in self]))
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 977, in render_annotated
+ return self.render(context)
+ ^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/defaulttags.py", line 327, in render
+ return nodelist.render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 1016, in render
+ return SafeString("".join([node.render_annotated(context) for node in self]))
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 977, in render_annotated
+ return self.render(context)
+ ^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/defaulttags.py", line 480, in render
+ url = reverse(view_name, args=args, kwargs=kwargs, current_app=current_app)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/urls/base.py", line 98, in reverse
+ resolved_url = resolver._reverse_with_prefix(view, prefix, *args, **kwargs)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/urls/resolvers.py", line 831, in _reverse_with_prefix
+ raise NoReverseMatch(msg)
+django.urls.exceptions.NoReverseMatch: Reverse for 'encounter_detail' with arguments '(UUID('23e89bd9-30d2-4da2-accd-8579ce105ca3'),)' not found. 1 pattern(s) tried: ['en/emr/encounters/(?P[0-9]+)/\\Z']
+ERROR 2025-09-06 20:51:54,501 basehttp 62923 6193246208 "GET /en/billing/bills/a668a9c6-ab05-40eb-96f3-5c56e1efc6d9/ HTTP/1.1" 500 201537
+WARNING 2025-09-06 20:51:54,519 log 62923 6193246208 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-06 20:51:54,519 basehttp 62923 6193246208 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-06 20:52:38,832 basehttp 62923 6193246208 "GET /en/billing/bills/a668a9c6-ab05-40eb-96f3-5c56e1efc6d9/ HTTP/1.1" 200 40744
+WARNING 2025-09-06 20:52:38,849 log 62923 6193246208 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-06 20:52:38,849 basehttp 62923 6193246208 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-06 20:52:38,891 basehttp 62923 6193246208 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-06 20:53:38,899 basehttp 62923 6193246208 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-06 20:53:44,589 autoreload 62923 8747049152 /Users/marwanalwali/manus_project/hospital_management_system_v4/emr/urls.py changed, reloading.
+INFO 2025-09-06 20:53:45,035 autoreload 75155 8747049152 Watching for file changes with StatReloader
+INFO 2025-09-06 20:53:45,500 basehttp 75155 6163345408 "GET /en/billing/bills/a668a9c6-ab05-40eb-96f3-5c56e1efc6d9/ HTTP/1.1" 200 40777
+WARNING 2025-09-06 20:53:45,518 log 75155 6163345408 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-06 20:53:45,519 basehttp 75155 6163345408 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-06 20:53:45,565 basehttp 75155 6163345408 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+WARNING 2025-09-06 20:53:48,154 log 75155 6196998144 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-06 20:53:48,155 basehttp 75155 6196998144 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-06 20:53:48,160 basehttp 75155 6163345408 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-06 20:53:48,164 basehttp 75155 6180171776 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4938
+WARNING 2025-09-06 20:53:48,190 log 75155 6180171776 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-06 20:53:48,190 basehttp 75155 6180171776 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-06 20:53:48,846 basehttp 75155 6180171776 "GET /en/billing/bills/ HTTP/1.1" 200 101540
+WARNING 2025-09-06 20:53:48,861 log 75155 6180171776 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-06 20:53:48,861 basehttp 75155 6180171776 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-06 20:53:48,924 basehttp 75155 6180171776 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-06 20:53:48,927 basehttp 75155 6163345408 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4938
+INFO 2025-09-06 20:53:50,969 basehttp 75155 6163345408 "GET /en/billing/bills/a668a9c6-ab05-40eb-96f3-5c56e1efc6d9/ HTTP/1.1" 200 40777
+WARNING 2025-09-06 20:53:50,995 log 75155 6163345408 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-06 20:53:50,995 basehttp 75155 6163345408 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-06 20:53:51,034 basehttp 75155 6163345408 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+WARNING 2025-09-06 20:53:55,492 log 75155 6163345408 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-06 20:53:55,493 basehttp 75155 6163345408 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+WARNING 2025-09-06 20:53:55,504 log 75155 6163345408 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-06 20:53:55,504 basehttp 75155 6163345408 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-06 20:53:59,272 basehttp 75155 6163345408 "GET /en/billing/bills/ HTTP/1.1" 200 101540
+WARNING 2025-09-06 20:53:59,288 log 75155 6163345408 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-06 20:53:59,288 basehttp 75155 6163345408 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-06 20:53:59,349 basehttp 75155 6163345408 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-06 20:53:59,351 basehttp 75155 6180171776 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4938
+INFO 2025-09-06 20:54:03,209 basehttp 75155 6180171776 "GET /en/billing/bills/a668a9c6-ab05-40eb-96f3-5c56e1efc6d9/edit/ HTTP/1.1" 200 110457
+WARNING 2025-09-06 20:54:03,231 log 75155 6180171776 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-06 20:54:03,231 basehttp 75155 6180171776 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-06 20:54:03,275 basehttp 75155 6180171776 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+WARNING 2025-09-06 20:54:08,801 log 75155 6180171776 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-06 20:54:08,801 basehttp 75155 6180171776 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+WARNING 2025-09-06 20:54:08,833 log 75155 6180171776 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-06 20:54:08,833 basehttp 75155 6180171776 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+ERROR 2025-09-06 20:54:14,430 log 75155 6180171776 Internal Server Error: /en/billing/bills/49ecf1c4-8024-4107-ad14-0d46cf66fe79/
+Traceback (most recent call last):
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/core/handlers/exception.py", line 55, in inner
+ response = get_response(request)
+ ^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/core/handlers/base.py", line 220, in _get_response
+ response = response.render()
+ ^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/response.py", line 114, in render
+ self.content = self.rendered_content
+ ^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/response.py", line 92, in rendered_content
+ return template.render(context, self._request)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/backends/django.py", line 107, in render
+ return self.template.render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 171, in render
+ return self._render(context)
+ ^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 163, in _render
+ return self.nodelist.render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 1016, in render
+ return SafeString("".join([node.render_annotated(context) for node in self]))
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 977, in render_annotated
+ return self.render(context)
+ ^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/loader_tags.py", line 159, in render
+ return compiled_parent._render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 163, in _render
+ return self.nodelist.render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 1016, in render
+ return SafeString("".join([node.render_annotated(context) for node in self]))
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 977, in render_annotated
+ return self.render(context)
+ ^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/loader_tags.py", line 65, in render
+ result = block.nodelist.render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 1016, in render
+ return SafeString("".join([node.render_annotated(context) for node in self]))
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 977, in render_annotated
+ return self.render(context)
+ ^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/defaulttags.py", line 243, in render
+ nodelist.append(node.render_annotated(context))
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 977, in render_annotated
+ return self.render(context)
+ ^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/defaulttags.py", line 480, in render
+ url = reverse(view_name, args=args, kwargs=kwargs, current_app=current_app)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/urls/base.py", line 98, in reverse
+ resolved_url = resolver._reverse_with_prefix(view, prefix, *args, **kwargs)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/urls/resolvers.py", line 831, in _reverse_with_prefix
+ raise NoReverseMatch(msg)
+django.urls.exceptions.NoReverseMatch: Reverse for 'claim_print' not found. 'claim_print' is not a valid view function or pattern name.
+ERROR 2025-09-06 20:54:14,431 basehttp 75155 6180171776 "GET /en/billing/bills/49ecf1c4-8024-4107-ad14-0d46cf66fe79/ HTTP/1.1" 500 194361
+WARNING 2025-09-06 20:54:14,448 log 75155 6180171776 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-06 20:54:14,448 basehttp 75155 6180171776 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-06 20:55:26,412 basehttp 75155 6180171776 "GET /en/billing/bills/49ecf1c4-8024-4107-ad14-0d46cf66fe79/ HTTP/1.1" 200 38565
+WARNING 2025-09-06 20:55:26,428 log 75155 6180171776 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-06 20:55:26,428 basehttp 75155 6180171776 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-06 20:55:26,471 basehttp 75155 6180171776 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+ERROR 2025-09-06 20:55:32,484 log 75155 6180171776 Internal Server Error: /en/billing/claims/172084ad-de1a-44f4-b67d-f89f27dca7dc/
+Traceback (most recent call last):
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/core/handlers/exception.py", line 55, in inner
+ response = get_response(request)
+ ^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/core/handlers/base.py", line 197, in _get_response
+ response = wrapped_callback(request, *callback_args, **callback_kwargs)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/views/generic/base.py", line 105, in view
+ return self.dispatch(request, *args, **kwargs)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/contrib/auth/mixins.py", line 73, in dispatch
+ return super().dispatch(request, *args, **kwargs)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/views/generic/base.py", line 144, in dispatch
+ return handler(request, *args, **kwargs)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/views/generic/detail.py", line 113, in get
+ context = self.get_context_data(object=self.object)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/billing/views.py", line 396, in get_context_data
+ context['status_updates'] = claim.claimstatusupdate_set.all().order_by('-update_date')
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+AttributeError: 'InsuranceClaim' object has no attribute 'claimstatusupdate_set'
+ERROR 2025-09-06 20:55:32,488 basehttp 75155 6180171776 "GET /en/billing/claims/172084ad-de1a-44f4-b67d-f89f27dca7dc/ HTTP/1.1" 500 87057
+WARNING 2025-09-06 20:55:32,505 log 75155 6180171776 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-06 20:55:32,505 basehttp 75155 6180171776 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-06 20:58:35,611 autoreload 75155 8747049152 /Users/marwanalwali/manus_project/hospital_management_system_v4/billing/views.py changed, reloading.
+INFO 2025-09-06 20:58:36,030 autoreload 77344 8747049152 Watching for file changes with StatReloader
+ERROR 2025-09-06 20:58:37,142 log 77344 6157611008 Internal Server Error: /en/billing/claims/172084ad-de1a-44f4-b67d-f89f27dca7dc/
+Traceback (most recent call last):
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/core/handlers/exception.py", line 55, in inner
+ response = get_response(request)
+ ^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/core/handlers/base.py", line 220, in _get_response
+ response = response.render()
+ ^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/response.py", line 114, in render
+ self.content = self.rendered_content
+ ^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/response.py", line 92, in rendered_content
+ return template.render(context, self._request)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/backends/django.py", line 107, in render
+ return self.template.render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 171, in render
+ return self._render(context)
+ ^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 163, in _render
+ return self.nodelist.render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 1016, in render
+ return SafeString("".join([node.render_annotated(context) for node in self]))
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 977, in render_annotated
+ return self.render(context)
+ ^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/loader_tags.py", line 159, in render
+ return compiled_parent._render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 163, in _render
+ return self.nodelist.render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 1016, in render
+ return SafeString("".join([node.render_annotated(context) for node in self]))
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 977, in render_annotated
+ return self.render(context)
+ ^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/loader_tags.py", line 65, in render
+ result = block.nodelist.render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 1016, in render
+ return SafeString("".join([node.render_annotated(context) for node in self]))
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 977, in render_annotated
+ return self.render(context)
+ ^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/defaulttags.py", line 480, in render
+ url = reverse(view_name, args=args, kwargs=kwargs, current_app=current_app)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/urls/base.py", line 98, in reverse
+ resolved_url = resolver._reverse_with_prefix(view, prefix, *args, **kwargs)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/urls/resolvers.py", line 831, in _reverse_with_prefix
+ raise NoReverseMatch(msg)
+django.urls.exceptions.NoReverseMatch: Reverse for 'claim_print' not found. 'claim_print' is not a valid view function or pattern name.
+ERROR 2025-09-06 20:58:37,144 basehttp 77344 6157611008 "GET /en/billing/claims/172084ad-de1a-44f4-b67d-f89f27dca7dc/ HTTP/1.1" 500 176843
+WARNING 2025-09-06 20:58:37,155 log 77344 6157611008 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-06 20:58:37,155 basehttp 77344 6157611008 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+ERROR 2025-09-06 20:58:38,805 log 77344 6157611008 Internal Server Error: /en/billing/claims/172084ad-de1a-44f4-b67d-f89f27dca7dc/
+Traceback (most recent call last):
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/core/handlers/exception.py", line 55, in inner
+ response = get_response(request)
+ ^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/core/handlers/base.py", line 220, in _get_response
+ response = response.render()
+ ^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/response.py", line 114, in render
+ self.content = self.rendered_content
+ ^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/response.py", line 92, in rendered_content
+ return template.render(context, self._request)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/backends/django.py", line 107, in render
+ return self.template.render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 171, in render
+ return self._render(context)
+ ^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 163, in _render
+ return self.nodelist.render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 1016, in render
+ return SafeString("".join([node.render_annotated(context) for node in self]))
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 977, in render_annotated
+ return self.render(context)
+ ^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/loader_tags.py", line 159, in render
+ return compiled_parent._render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 163, in _render
+ return self.nodelist.render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 1016, in render
+ return SafeString("".join([node.render_annotated(context) for node in self]))
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 977, in render_annotated
+ return self.render(context)
+ ^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/loader_tags.py", line 65, in render
+ result = block.nodelist.render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 1016, in render
+ return SafeString("".join([node.render_annotated(context) for node in self]))
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 977, in render_annotated
+ return self.render(context)
+ ^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/defaulttags.py", line 480, in render
+ url = reverse(view_name, args=args, kwargs=kwargs, current_app=current_app)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/urls/base.py", line 98, in reverse
+ resolved_url = resolver._reverse_with_prefix(view, prefix, *args, **kwargs)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/urls/resolvers.py", line 831, in _reverse_with_prefix
+ raise NoReverseMatch(msg)
+django.urls.exceptions.NoReverseMatch: Reverse for 'claim_print' not found. 'claim_print' is not a valid view function or pattern name.
+ERROR 2025-09-06 20:58:38,806 basehttp 77344 6157611008 "GET /en/billing/claims/172084ad-de1a-44f4-b67d-f89f27dca7dc/ HTTP/1.1" 500 176843
+WARNING 2025-09-06 20:58:38,822 log 77344 6157611008 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-06 20:58:38,822 basehttp 77344 6157611008 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+ERROR 2025-09-06 20:59:09,893 log 77344 6157611008 Internal Server Error: /en/billing/claims/172084ad-de1a-44f4-b67d-f89f27dca7dc/
+Traceback (most recent call last):
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/core/handlers/exception.py", line 55, in inner
+ response = get_response(request)
+ ^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/core/handlers/base.py", line 220, in _get_response
+ response = response.render()
+ ^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/response.py", line 114, in render
+ self.content = self.rendered_content
+ ^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/response.py", line 92, in rendered_content
+ return template.render(context, self._request)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/backends/django.py", line 107, in render
+ return self.template.render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 171, in render
+ return self._render(context)
+ ^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 163, in _render
+ return self.nodelist.render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 1016, in render
+ return SafeString("".join([node.render_annotated(context) for node in self]))
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 977, in render_annotated
+ return self.render(context)
+ ^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/loader_tags.py", line 159, in render
+ return compiled_parent._render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 163, in _render
+ return self.nodelist.render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 1016, in render
+ return SafeString("".join([node.render_annotated(context) for node in self]))
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 977, in render_annotated
+ return self.render(context)
+ ^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/loader_tags.py", line 65, in render
+ result = block.nodelist.render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 1016, in render
+ return SafeString("".join([node.render_annotated(context) for node in self]))
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 977, in render_annotated
+ return self.render(context)
+ ^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/defaulttags.py", line 480, in render
+ url = reverse(view_name, args=args, kwargs=kwargs, current_app=current_app)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/urls/base.py", line 98, in reverse
+ resolved_url = resolver._reverse_with_prefix(view, prefix, *args, **kwargs)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/urls/resolvers.py", line 831, in _reverse_with_prefix
+ raise NoReverseMatch(msg)
+django.urls.exceptions.NoReverseMatch: Reverse for 'claim_download' not found. 'claim_download' is not a valid view function or pattern name.
+ERROR 2025-09-06 20:59:09,894 basehttp 77344 6157611008 "GET /en/billing/claims/172084ad-de1a-44f4-b67d-f89f27dca7dc/ HTTP/1.1" 500 176762
+WARNING 2025-09-06 20:59:09,908 log 77344 6157611008 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-06 20:59:09,908 basehttp 77344 6157611008 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+ERROR 2025-09-06 20:59:38,455 log 77344 6157611008 Internal Server Error: /en/billing/claims/172084ad-de1a-44f4-b67d-f89f27dca7dc/
+Traceback (most recent call last):
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/core/handlers/exception.py", line 55, in inner
+ response = get_response(request)
+ ^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/core/handlers/base.py", line 220, in _get_response
+ response = response.render()
+ ^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/response.py", line 114, in render
+ self.content = self.rendered_content
+ ^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/response.py", line 92, in rendered_content
+ return template.render(context, self._request)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/backends/django.py", line 107, in render
+ return self.template.render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 171, in render
+ return self._render(context)
+ ^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 163, in _render
+ return self.nodelist.render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 1016, in render
+ return SafeString("".join([node.render_annotated(context) for node in self]))
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 977, in render_annotated
+ return self.render(context)
+ ^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/loader_tags.py", line 159, in render
+ return compiled_parent._render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 163, in _render
+ return self.nodelist.render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 1016, in render
+ return SafeString("".join([node.render_annotated(context) for node in self]))
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 977, in render_annotated
+ return self.render(context)
+ ^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/loader_tags.py", line 65, in render
+ result = block.nodelist.render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 1016, in render
+ return SafeString("".join([node.render_annotated(context) for node in self]))
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 977, in render_annotated
+ return self.render(context)
+ ^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/defaulttags.py", line 480, in render
+ url = reverse(view_name, args=args, kwargs=kwargs, current_app=current_app)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/urls/base.py", line 98, in reverse
+ resolved_url = resolver._reverse_with_prefix(view, prefix, *args, **kwargs)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/urls/resolvers.py", line 831, in _reverse_with_prefix
+ raise NoReverseMatch(msg)
+django.urls.exceptions.NoReverseMatch: Reverse for 'claim_download' not found. 'claim_download' is not a valid view function or pattern name.
+ERROR 2025-09-06 20:59:38,456 basehttp 77344 6157611008 "GET /en/billing/claims/172084ad-de1a-44f4-b67d-f89f27dca7dc/ HTTP/1.1" 500 176671
+WARNING 2025-09-06 20:59:38,469 log 77344 6157611008 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-06 20:59:38,469 basehttp 77344 6157611008 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+ERROR 2025-09-06 20:59:50,130 log 77344 6157611008 Internal Server Error: /en/billing/claims/172084ad-de1a-44f4-b67d-f89f27dca7dc/
+Traceback (most recent call last):
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/core/handlers/exception.py", line 55, in inner
+ response = get_response(request)
+ ^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/core/handlers/base.py", line 220, in _get_response
+ response = response.render()
+ ^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/response.py", line 114, in render
+ self.content = self.rendered_content
+ ^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/response.py", line 92, in rendered_content
+ return template.render(context, self._request)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/backends/django.py", line 107, in render
+ return self.template.render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 171, in render
+ return self._render(context)
+ ^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 163, in _render
+ return self.nodelist.render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 1016, in render
+ return SafeString("".join([node.render_annotated(context) for node in self]))
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 977, in render_annotated
+ return self.render(context)
+ ^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/loader_tags.py", line 159, in render
+ return compiled_parent._render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 163, in _render
+ return self.nodelist.render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 1016, in render
+ return SafeString("".join([node.render_annotated(context) for node in self]))
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 977, in render_annotated
+ return self.render(context)
+ ^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/loader_tags.py", line 65, in render
+ result = block.nodelist.render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 1016, in render
+ return SafeString("".join([node.render_annotated(context) for node in self]))
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 977, in render_annotated
+ return self.render(context)
+ ^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/defaulttags.py", line 327, in render
+ return nodelist.render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 1016, in render
+ return SafeString("".join([node.render_annotated(context) for node in self]))
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 977, in render_annotated
+ return self.render(context)
+ ^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/defaulttags.py", line 480, in render
+ url = reverse(view_name, args=args, kwargs=kwargs, current_app=current_app)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/urls/base.py", line 98, in reverse
+ resolved_url = resolver._reverse_with_prefix(view, prefix, *args, **kwargs)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/urls/resolvers.py", line 831, in _reverse_with_prefix
+ raise NoReverseMatch(msg)
+django.urls.exceptions.NoReverseMatch: Reverse for 'claim_status_check' not found. 'claim_status_check' is not a valid view function or pattern name.
+ERROR 2025-09-06 20:59:50,131 basehttp 77344 6157611008 "GET /en/billing/claims/172084ad-de1a-44f4-b67d-f89f27dca7dc/ HTTP/1.1" 500 190725
+WARNING 2025-09-06 20:59:50,143 log 77344 6157611008 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-06 20:59:50,143 basehttp 77344 6157611008 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+ERROR 2025-09-06 21:00:01,988 log 77344 6157611008 Internal Server Error: /en/billing/claims/172084ad-de1a-44f4-b67d-f89f27dca7dc/
+Traceback (most recent call last):
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/core/handlers/exception.py", line 55, in inner
+ response = get_response(request)
+ ^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/core/handlers/base.py", line 220, in _get_response
+ response = response.render()
+ ^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/response.py", line 114, in render
+ self.content = self.rendered_content
+ ^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/response.py", line 92, in rendered_content
+ return template.render(context, self._request)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/backends/django.py", line 107, in render
+ return self.template.render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 171, in render
+ return self._render(context)
+ ^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 163, in _render
+ return self.nodelist.render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 1016, in render
+ return SafeString("".join([node.render_annotated(context) for node in self]))
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 977, in render_annotated
+ return self.render(context)
+ ^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/loader_tags.py", line 159, in render
+ return compiled_parent._render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 163, in _render
+ return self.nodelist.render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 1016, in render
+ return SafeString("".join([node.render_annotated(context) for node in self]))
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 977, in render_annotated
+ return self.render(context)
+ ^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/loader_tags.py", line 65, in render
+ result = block.nodelist.render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 1016, in render
+ return SafeString("".join([node.render_annotated(context) for node in self]))
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 977, in render_annotated
+ return self.render(context)
+ ^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/defaulttags.py", line 327, in render
+ return nodelist.render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 1016, in render
+ return SafeString("".join([node.render_annotated(context) for node in self]))
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 977, in render_annotated
+ return self.render(context)
+ ^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/defaulttags.py", line 480, in render
+ url = reverse(view_name, args=args, kwargs=kwargs, current_app=current_app)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/urls/base.py", line 98, in reverse
+ resolved_url = resolver._reverse_with_prefix(view, prefix, *args, **kwargs)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/urls/resolvers.py", line 831, in _reverse_with_prefix
+ raise NoReverseMatch(msg)
+django.urls.exceptions.NoReverseMatch: Reverse for 'claim_status_check' not found. 'claim_status_check' is not a valid view function or pattern name.
+ERROR 2025-09-06 21:00:01,989 basehttp 77344 6157611008 "GET /en/billing/claims/172084ad-de1a-44f4-b67d-f89f27dca7dc/ HTTP/1.1" 500 191087
+WARNING 2025-09-06 21:00:02,004 log 77344 6157611008 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-06 21:00:02,004 basehttp 77344 6157611008 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+ERROR 2025-09-06 21:00:16,339 log 77344 6157611008 Internal Server Error: /en/billing/claims/172084ad-de1a-44f4-b67d-f89f27dca7dc/
+Traceback (most recent call last):
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/core/handlers/exception.py", line 55, in inner
+ response = get_response(request)
+ ^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/core/handlers/base.py", line 220, in _get_response
+ response = response.render()
+ ^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/response.py", line 114, in render
+ self.content = self.rendered_content
+ ^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/response.py", line 92, in rendered_content
+ return template.render(context, self._request)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/backends/django.py", line 107, in render
+ return self.template.render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 171, in render
+ return self._render(context)
+ ^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 163, in _render
+ return self.nodelist.render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 1016, in render
+ return SafeString("".join([node.render_annotated(context) for node in self]))
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 977, in render_annotated
+ return self.render(context)
+ ^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/loader_tags.py", line 159, in render
+ return compiled_parent._render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 163, in _render
+ return self.nodelist.render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 1016, in render
+ return SafeString("".join([node.render_annotated(context) for node in self]))
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 977, in render_annotated
+ return self.render(context)
+ ^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/loader_tags.py", line 65, in render
+ result = block.nodelist.render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 1016, in render
+ return SafeString("".join([node.render_annotated(context) for node in self]))
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 977, in render_annotated
+ return self.render(context)
+ ^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/defaulttags.py", line 480, in render
+ url = reverse(view_name, args=args, kwargs=kwargs, current_app=current_app)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/urls/base.py", line 98, in reverse
+ resolved_url = resolver._reverse_with_prefix(view, prefix, *args, **kwargs)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/urls/resolvers.py", line 831, in _reverse_with_prefix
+ raise NoReverseMatch(msg)
+django.urls.exceptions.NoReverseMatch: Reverse for 'claim_print' not found. 'claim_print' is not a valid view function or pattern name.
+ERROR 2025-09-06 21:00:16,340 basehttp 77344 6157611008 "GET /en/billing/claims/172084ad-de1a-44f4-b67d-f89f27dca7dc/ HTTP/1.1" 500 176728
+WARNING 2025-09-06 21:00:16,353 log 77344 6157611008 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-06 21:00:16,353 basehttp 77344 6157611008 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+ERROR 2025-09-06 21:00:27,731 log 77344 6157611008 Internal Server Error: /en/billing/claims/172084ad-de1a-44f4-b67d-f89f27dca7dc/
+Traceback (most recent call last):
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/core/handlers/exception.py", line 55, in inner
+ response = get_response(request)
+ ^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/core/handlers/base.py", line 220, in _get_response
+ response = response.render()
+ ^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/response.py", line 114, in render
+ self.content = self.rendered_content
+ ^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/response.py", line 92, in rendered_content
+ return template.render(context, self._request)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/backends/django.py", line 107, in render
+ return self.template.render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 171, in render
+ return self._render(context)
+ ^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 163, in _render
+ return self.nodelist.render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 1016, in render
+ return SafeString("".join([node.render_annotated(context) for node in self]))
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 977, in render_annotated
+ return self.render(context)
+ ^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/loader_tags.py", line 159, in render
+ return compiled_parent._render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 163, in _render
+ return self.nodelist.render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 1016, in render
+ return SafeString("".join([node.render_annotated(context) for node in self]))
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 977, in render_annotated
+ return self.render(context)
+ ^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/loader_tags.py", line 65, in render
+ result = block.nodelist.render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 1016, in render
+ return SafeString("".join([node.render_annotated(context) for node in self]))
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 977, in render_annotated
+ return self.render(context)
+ ^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/defaulttags.py", line 480, in render
+ url = reverse(view_name, args=args, kwargs=kwargs, current_app=current_app)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/urls/base.py", line 98, in reverse
+ resolved_url = resolver._reverse_with_prefix(view, prefix, *args, **kwargs)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/urls/resolvers.py", line 831, in _reverse_with_prefix
+ raise NoReverseMatch(msg)
+django.urls.exceptions.NoReverseMatch: Reverse for 'claim_download' not found. 'claim_download' is not a valid view function or pattern name.
+ERROR 2025-09-06 21:00:27,732 basehttp 77344 6157611008 "GET /en/billing/claims/172084ad-de1a-44f4-b67d-f89f27dca7dc/ HTTP/1.1" 500 176265
+WARNING 2025-09-06 21:00:27,745 log 77344 6157611008 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-06 21:00:27,745 basehttp 77344 6157611008 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+ERROR 2025-09-06 21:00:39,384 log 77344 6157611008 Internal Server Error: /en/billing/claims/172084ad-de1a-44f4-b67d-f89f27dca7dc/
+Traceback (most recent call last):
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/core/handlers/exception.py", line 55, in inner
+ response = get_response(request)
+ ^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/core/handlers/base.py", line 220, in _get_response
+ response = response.render()
+ ^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/response.py", line 114, in render
+ self.content = self.rendered_content
+ ^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/response.py", line 92, in rendered_content
+ return template.render(context, self._request)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/backends/django.py", line 107, in render
+ return self.template.render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 171, in render
+ return self._render(context)
+ ^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 163, in _render
+ return self.nodelist.render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 1016, in render
+ return SafeString("".join([node.render_annotated(context) for node in self]))
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 977, in render_annotated
+ return self.render(context)
+ ^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/loader_tags.py", line 159, in render
+ return compiled_parent._render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 163, in _render
+ return self.nodelist.render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 1016, in render
+ return SafeString("".join([node.render_annotated(context) for node in self]))
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 977, in render_annotated
+ return self.render(context)
+ ^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/loader_tags.py", line 65, in render
+ result = block.nodelist.render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 1016, in render
+ return SafeString("".join([node.render_annotated(context) for node in self]))
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 977, in render_annotated
+ return self.render(context)
+ ^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/defaulttags.py", line 327, in render
+ return nodelist.render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 1016, in render
+ return SafeString("".join([node.render_annotated(context) for node in self]))
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 977, in render_annotated
+ return self.render(context)
+ ^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 1075, in render
+ output = self.filter_expression.resolve(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 749, in resolve
+ new_obj = func(obj, *arg_vals)
+ ^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/defaultfilters.py", line 784, in date
+ return formats.date_format(value, arg)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/utils/formats.py", line 155, in date_format
+ return dateformat.format(
+ ^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/utils/dateformat.py", line 325, in format
+ return df.format(format_string)
+ ^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/utils/dateformat.py", line 45, in format
+ raise TypeError(
+TypeError: The format for date objects may not contain time-related format specifiers (found 'g').
+ERROR 2025-09-06 21:00:39,385 basehttp 77344 6157611008 "GET /en/billing/claims/172084ad-de1a-44f4-b67d-f89f27dca7dc/ HTTP/1.1" 500 198633
+WARNING 2025-09-06 21:00:39,399 log 77344 6157611008 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-06 21:00:39,399 basehttp 77344 6157611008 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-06 21:01:06,361 basehttp 77344 6157611008 "GET /en/billing/claims/172084ad-de1a-44f4-b67d-f89f27dca7dc/ HTTP/1.1" 200 37484
+WARNING 2025-09-06 21:01:06,378 log 77344 6157611008 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-06 21:01:06,378 basehttp 77344 6157611008 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-06 21:01:06,451 basehttp 77344 6157611008 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-06 21:01:27,610 basehttp 77344 6157611008 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+WARNING 2025-09-06 21:01:27,612 log 77344 6174437376 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-06 21:01:27,612 basehttp 77344 6174437376 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+WARNING 2025-09-06 21:01:27,627 log 77344 6174437376 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-06 21:01:27,627 basehttp 77344 6174437376 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-06 21:01:31,347 basehttp 77344 6174437376 "GET /en/billing/payments/create/?bill=49ecf1c4-8024-4107-ad14-0d46cf66fe79 HTTP/1.1" 200 42101
+WARNING 2025-09-06 21:01:31,368 log 77344 6174437376 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-06 21:01:31,368 basehttp 77344 6174437376 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-06 21:01:31,438 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-06 21:02:31,455 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-06 21:03:31,438 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-06 21:04:31,453 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-06 21:05:20,613 basehttp 77344 6174437376 "GET /en/billing/payments/create/?bill=49ecf1c4-8024-4107-ad14-0d46cf66fe79 HTTP/1.1" 200 42101
+WARNING 2025-09-06 21:05:20,633 log 77344 6174437376 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-06 21:05:20,633 basehttp 77344 6174437376 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-06 21:05:20,698 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-06 21:05:22,185 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+WARNING 2025-09-06 21:05:22,187 log 77344 6157611008 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-06 21:05:22,187 basehttp 77344 6157611008 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+WARNING 2025-09-06 21:05:22,200 log 77344 6157611008 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-06 21:05:22,200 basehttp 77344 6157611008 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-06 21:05:22,728 basehttp 77344 6157611008 "GET /en/billing/bills/49ecf1c4-8024-4107-ad14-0d46cf66fe79/ HTTP/1.1" 200 38565
+WARNING 2025-09-06 21:05:22,744 log 77344 6157611008 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-06 21:05:22,744 basehttp 77344 6157611008 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-06 21:05:22,787 basehttp 77344 6157611008 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-06 21:06:22,791 basehttp 77344 6157611008 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-06 21:07:22,802 basehttp 77344 6157611008 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-06 21:07:53,414 basehttp 77344 6157611008 "GET /en/billing/payments/create/?bill=49ecf1c4-8024-4107-ad14-0d46cf66fe79 HTTP/1.1" 200 42101
+WARNING 2025-09-06 21:07:53,429 log 77344 6157611008 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-06 21:07:53,430 basehttp 77344 6157611008 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-06 21:07:53,475 basehttp 77344 6157611008 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+WARNING 2025-09-06 21:07:59,928 log 77344 6157611008 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-06 21:07:59,928 basehttp 77344 6157611008 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+WARNING 2025-09-06 21:07:59,941 log 77344 6157611008 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-06 21:07:59,941 basehttp 77344 6157611008 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-06 21:08:22,808 basehttp 77344 6157611008 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-06 21:08:23,620 basehttp 77344 6157611008 "GET /en/billing/claims/172084ad-de1a-44f4-b67d-f89f27dca7dc/ HTTP/1.1" 200 37650
+WARNING 2025-09-06 21:08:23,640 log 77344 6157611008 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-06 21:08:23,640 basehttp 77344 6157611008 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-06 21:08:23,683 basehttp 77344 6157611008 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-06 21:08:27,797 basehttp 77344 6157611008 "GET /en/billing/claims/172084ad-de1a-44f4-b67d-f89f27dca7dc/ HTTP/1.1" 200 37650
+WARNING 2025-09-06 21:08:27,815 log 77344 6157611008 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-06 21:08:27,816 basehttp 77344 6157611008 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-06 21:08:27,853 basehttp 77344 6157611008 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+WARNING 2025-09-06 21:08:35,506 log 77344 6157611008 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-06 21:08:35,506 basehttp 77344 6157611008 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+WARNING 2025-09-06 21:08:35,518 log 77344 6157611008 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-06 21:08:35,518 basehttp 77344 6157611008 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+WARNING 2025-09-06 21:08:35,894 log 77344 6157611008 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-06 21:08:35,894 basehttp 77344 6157611008 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-06 21:09:35,940 basehttp 77344 6157611008 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-06 21:09:35,945 basehttp 77344 6174437376 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4938
+INFO 2025-09-06 21:10:35,950 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-06 21:10:35,952 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4938
+INFO 2025-09-06 21:11:35,955 basehttp 77344 6157611008 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-06 21:11:35,958 basehttp 77344 6174437376 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4938
+INFO 2025-09-06 21:12:35,949 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-06 21:12:35,952 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4938
+INFO 2025-09-06 21:13:35,952 basehttp 77344 6157611008 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-06 21:13:35,955 basehttp 77344 6174437376 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4938
+INFO 2025-09-06 21:14:35,958 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-06 21:14:35,961 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4938
+INFO 2025-09-06 21:15:35,955 basehttp 77344 6157611008 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-06 21:15:35,958 basehttp 77344 6174437376 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4938
+INFO 2025-09-06 21:16:35,958 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-06 21:16:35,961 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4938
+INFO 2025-09-06 21:17:35,967 basehttp 77344 6157611008 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-06 21:17:35,970 basehttp 77344 6174437376 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4938
+INFO 2025-09-06 21:18:35,945 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-06 21:18:35,948 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4938
+INFO 2025-09-06 21:19:36,239 basehttp 77344 6157611008 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-06 21:19:36,243 basehttp 77344 6174437376 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4938
+INFO 2025-09-06 21:20:38,239 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-06 21:20:38,242 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4938
+INFO 2025-09-06 21:23:50,004 basehttp 77344 6157611008 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-06 21:23:50,007 basehttp 77344 6174437376 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4938
+INFO 2025-09-06 21:25:50,011 basehttp 77344 6157611008 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-06 21:25:50,015 basehttp 77344 6174437376 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4938
+INFO 2025-09-06 21:28:17,699 basehttp 77344 6157611008 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-06 21:28:17,702 basehttp 77344 6174437376 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4938
+INFO 2025-09-06 21:30:17,696 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-06 21:30:17,699 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4938
+INFO 2025-09-06 21:32:41,898 basehttp 77344 6157611008 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-06 21:32:41,901 basehttp 77344 6174437376 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4938
+INFO 2025-09-06 21:39:08,829 basehttp 77344 6157611008 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-06 21:39:08,832 basehttp 77344 6174437376 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4938
+INFO 2025-09-06 21:41:08,820 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-06 21:41:08,823 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4938
+INFO 2025-09-06 21:43:08,820 basehttp 77344 6157611008 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-06 21:43:08,823 basehttp 77344 6174437376 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4938
+INFO 2025-09-06 21:45:08,818 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-06 21:45:08,821 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4938
+INFO 2025-09-06 21:47:08,816 basehttp 77344 6157611008 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-06 21:47:08,818 basehttp 77344 6174437376 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4938
+INFO 2025-09-06 21:49:08,818 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-06 21:49:08,821 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4938
+INFO 2025-09-06 21:51:08,825 basehttp 77344 6157611008 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-06 21:51:08,826 basehttp 77344 6174437376 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4938
+INFO 2025-09-06 21:53:08,800 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-06 21:53:08,803 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4938
+INFO 2025-09-06 21:55:08,848 basehttp 77344 6157611008 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-06 21:55:08,851 basehttp 77344 6174437376 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4938
+INFO 2025-09-06 21:57:08,855 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-06 21:57:08,858 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4938
+INFO 2025-09-06 21:59:08,851 basehttp 77344 6157611008 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-06 21:59:08,854 basehttp 77344 6174437376 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4938
+INFO 2025-09-06 22:01:08,861 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-06 22:01:08,863 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4938
+INFO 2025-09-06 22:03:08,853 basehttp 77344 6157611008 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-06 22:03:08,856 basehttp 77344 6174437376 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4938
+INFO 2025-09-06 22:05:08,854 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-06 22:05:08,858 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4938
+INFO 2025-09-06 22:07:08,851 basehttp 77344 6157611008 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-06 22:07:08,854 basehttp 77344 6174437376 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4938
+INFO 2025-09-06 22:09:08,854 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-06 22:09:08,856 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4938
+INFO 2025-09-06 22:11:08,846 basehttp 77344 6157611008 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-06 22:11:08,849 basehttp 77344 6174437376 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4938
+INFO 2025-09-06 22:13:08,851 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-06 22:13:08,853 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4938
+INFO 2025-09-06 22:15:08,843 basehttp 77344 6157611008 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-06 22:15:08,846 basehttp 77344 6174437376 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4938
+INFO 2025-09-06 22:17:08,843 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-06 22:17:08,846 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4938
+INFO 2025-09-06 22:19:08,841 basehttp 77344 6157611008 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-06 22:19:08,844 basehttp 77344 6174437376 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4938
+INFO 2025-09-06 22:21:08,834 basehttp 77344 6157611008 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-06 22:21:08,837 basehttp 77344 6174437376 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4938
+INFO 2025-09-06 22:23:08,836 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-06 22:23:08,841 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4938
+INFO 2025-09-06 22:25:08,841 basehttp 77344 6157611008 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-06 22:25:08,844 basehttp 77344 6174437376 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4938
+INFO 2025-09-06 22:27:08,813 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-06 22:27:08,815 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4938
+INFO 2025-09-06 22:29:08,814 basehttp 77344 6157611008 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-06 22:29:08,817 basehttp 77344 6174437376 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4938
+INFO 2025-09-06 22:31:08,811 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-06 22:31:08,814 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4938
+INFO 2025-09-06 22:33:08,813 basehttp 77344 6157611008 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-06 22:33:08,815 basehttp 77344 6174437376 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4938
+INFO 2025-09-06 22:35:08,814 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-06 22:35:08,816 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4938
+INFO 2025-09-06 22:37:08,809 basehttp 77344 6157611008 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-06 22:37:08,813 basehttp 77344 6174437376 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4938
+INFO 2025-09-06 22:39:08,809 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-06 22:39:08,812 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4938
+INFO 2025-09-06 22:42:34,941 basehttp 77344 6157611008 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-06 22:42:34,943 basehttp 77344 6174437376 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4938
+INFO 2025-09-06 22:49:25,788 basehttp 77344 6157611008 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-06 22:49:25,791 basehttp 77344 6174437376 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4938
+INFO 2025-09-06 22:51:25,783 basehttp 77344 6157611008 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-06 22:51:25,786 basehttp 77344 6174437376 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4938
+INFO 2025-09-06 22:53:25,764 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-06 22:53:25,765 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4938
+INFO 2025-09-06 22:55:25,774 basehttp 77344 6157611008 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-06 22:55:25,777 basehttp 77344 6174437376 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4938
+INFO 2025-09-06 22:57:25,908 basehttp 77344 6157611008 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-06 22:57:25,911 basehttp 77344 6174437376 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4938
+INFO 2025-09-06 22:58:25,919 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-06 22:58:25,923 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4938
+INFO 2025-09-06 23:00:25,913 basehttp 77344 6157611008 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-06 23:00:25,915 basehttp 77344 6174437376 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4938
+INFO 2025-09-06 23:01:25,923 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-06 23:01:25,927 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4938
+INFO 2025-09-06 23:03:25,907 basehttp 77344 6157611008 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-06 23:03:25,910 basehttp 77344 6174437376 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4938
+INFO 2025-09-06 23:05:25,897 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-06 23:05:25,899 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4938
+INFO 2025-09-06 23:07:25,909 basehttp 77344 6157611008 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-06 23:07:25,913 basehttp 77344 6174437376 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4938
+INFO 2025-09-06 23:09:25,909 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-06 23:09:25,912 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4938
+INFO 2025-09-06 23:11:25,910 basehttp 77344 6157611008 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-06 23:11:25,914 basehttp 77344 6174437376 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4938
+INFO 2025-09-06 23:13:25,903 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-06 23:13:25,907 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4938
+INFO 2025-09-06 23:15:25,904 basehttp 77344 6157611008 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-06 23:15:25,907 basehttp 77344 6174437376 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4938
+INFO 2025-09-06 23:17:25,926 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-06 23:17:25,929 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4938
+INFO 2025-09-06 23:19:25,904 basehttp 77344 6157611008 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-06 23:19:25,908 basehttp 77344 6174437376 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4938
+INFO 2025-09-06 23:21:25,922 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-06 23:21:25,925 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4938
+INFO 2025-09-06 23:23:25,908 basehttp 77344 6157611008 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-06 23:23:25,911 basehttp 77344 6174437376 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4938
+INFO 2025-09-06 23:25:25,916 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-06 23:25:25,919 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4938
+INFO 2025-09-06 23:27:25,908 basehttp 77344 6157611008 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-06 23:27:25,913 basehttp 77344 6174437376 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4938
+INFO 2025-09-06 23:29:25,892 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-06 23:29:25,895 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4938
+INFO 2025-09-06 23:31:25,898 basehttp 77344 6157611008 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-06 23:31:25,901 basehttp 77344 6174437376 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4938
+INFO 2025-09-06 23:33:25,895 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-06 23:33:25,898 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4938
+INFO 2025-09-06 23:35:25,875 basehttp 77344 6157611008 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-06 23:35:25,878 basehttp 77344 6174437376 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4938
+INFO 2025-09-06 23:37:25,891 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-06 23:37:25,895 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4938
+INFO 2025-09-06 23:39:25,895 basehttp 77344 6157611008 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-06 23:39:25,898 basehttp 77344 6174437376 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4938
+INFO 2025-09-06 23:41:25,896 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-06 23:41:25,899 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4938
+INFO 2025-09-06 23:43:25,900 basehttp 77344 6157611008 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-06 23:43:25,903 basehttp 77344 6174437376 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4938
+INFO 2025-09-06 23:45:25,898 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-06 23:45:25,901 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4938
+INFO 2025-09-06 23:47:25,900 basehttp 77344 6157611008 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-06 23:47:25,903 basehttp 77344 6174437376 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4938
+INFO 2025-09-06 23:49:25,909 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-06 23:49:25,912 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4938
+INFO 2025-09-06 23:54:06,595 basehttp 77344 6157611008 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-06 23:54:06,598 basehttp 77344 6174437376 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4938
+INFO 2025-09-07 00:05:11,486 basehttp 77344 6157611008 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 00:05:11,489 basehttp 77344 6174437376 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4938
+INFO 2025-09-07 00:07:31,248 basehttp 77344 6157611008 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 00:07:31,251 basehttp 77344 6174437376 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4938
+INFO 2025-09-07 00:18:38,689 basehttp 77344 6157611008 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 00:18:38,693 basehttp 77344 6174437376 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4938
+INFO 2025-09-07 00:23:25,721 basehttp 77344 6157611008 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 00:23:25,724 basehttp 77344 6174437376 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4938
+INFO 2025-09-07 00:35:15,078 basehttp 77344 6157611008 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 00:35:15,082 basehttp 77344 6174437376 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4938
+INFO 2025-09-07 00:37:15,065 basehttp 77344 6157611008 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 00:37:15,068 basehttp 77344 6174437376 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4938
+INFO 2025-09-07 00:39:15,064 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 00:39:15,067 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4938
+INFO 2025-09-07 00:41:15,061 basehttp 77344 6157611008 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 00:41:15,064 basehttp 77344 6174437376 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4938
+INFO 2025-09-07 00:43:15,064 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 00:43:15,066 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4938
+INFO 2025-09-07 00:45:15,057 basehttp 77344 6157611008 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 00:45:15,060 basehttp 77344 6174437376 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4938
+INFO 2025-09-07 00:47:15,054 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 00:47:15,057 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4938
+INFO 2025-09-07 00:49:15,100 basehttp 77344 6157611008 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 00:49:15,103 basehttp 77344 6174437376 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4938
+INFO 2025-09-07 00:51:15,085 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 00:51:15,087 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4938
+INFO 2025-09-07 00:53:15,096 basehttp 77344 6157611008 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 00:53:15,098 basehttp 77344 6174437376 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4938
+INFO 2025-09-07 00:55:15,098 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 00:55:15,102 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4938
+INFO 2025-09-07 00:57:15,098 basehttp 77344 6157611008 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 00:57:15,100 basehttp 77344 6174437376 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4938
+INFO 2025-09-07 00:59:15,096 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 00:59:15,099 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4938
+INFO 2025-09-07 01:01:15,094 basehttp 77344 6157611008 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 01:01:15,098 basehttp 77344 6174437376 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4938
+INFO 2025-09-07 01:03:15,116 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 01:03:15,120 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4938
+INFO 2025-09-07 01:05:15,126 basehttp 77344 6157611008 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 01:05:15,129 basehttp 77344 6174437376 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4938
+INFO 2025-09-07 01:07:15,124 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 01:07:15,127 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4938
+INFO 2025-09-07 01:09:15,127 basehttp 77344 6157611008 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 01:09:15,129 basehttp 77344 6174437376 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4938
+INFO 2025-09-07 01:11:15,110 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 01:11:15,112 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4938
+INFO 2025-09-07 01:13:15,117 basehttp 77344 6157611008 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 01:13:15,119 basehttp 77344 6174437376 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4938
+INFO 2025-09-07 01:15:15,120 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 01:15:15,122 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4938
+INFO 2025-09-07 01:17:15,119 basehttp 77344 6157611008 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 01:17:15,121 basehttp 77344 6174437376 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4938
+INFO 2025-09-07 01:19:15,107 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 01:19:15,110 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4938
+INFO 2025-09-07 01:21:15,118 basehttp 77344 6157611008 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 01:21:15,121 basehttp 77344 6174437376 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4938
+INFO 2025-09-07 01:23:15,117 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 01:23:15,120 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4938
+INFO 2025-09-07 01:25:15,125 basehttp 77344 6157611008 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 01:25:15,128 basehttp 77344 6174437376 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4938
+INFO 2025-09-07 01:27:15,113 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 01:27:15,116 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4938
+INFO 2025-09-07 01:29:15,122 basehttp 77344 6157611008 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 01:29:15,124 basehttp 77344 6174437376 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4938
+INFO 2025-09-07 01:31:15,115 basehttp 77344 6157611008 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 01:31:15,118 basehttp 77344 6174437376 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4938
+INFO 2025-09-07 01:33:15,196 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 01:33:15,199 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4938
+INFO 2025-09-07 01:35:15,204 basehttp 77344 6157611008 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 01:35:15,207 basehttp 77344 6174437376 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4938
+INFO 2025-09-07 01:47:32,334 basehttp 77344 6157611008 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 01:47:32,337 basehttp 77344 6174437376 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4938
+INFO 2025-09-07 01:57:14,127 basehttp 77344 6157611008 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 01:57:14,130 basehttp 77344 6174437376 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4938
+INFO 2025-09-07 02:04:09,538 basehttp 77344 6157611008 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 02:04:09,542 basehttp 77344 6174437376 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4938
+INFO 2025-09-07 02:06:09,532 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 02:06:09,535 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4938
+INFO 2025-09-07 02:08:09,538 basehttp 77344 6157611008 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 02:08:09,540 basehttp 77344 6174437376 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4938
+INFO 2025-09-07 02:10:09,524 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 02:10:09,526 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4938
+INFO 2025-09-07 02:12:09,536 basehttp 77344 6157611008 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 02:12:09,539 basehttp 77344 6174437376 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4938
+INFO 2025-09-07 02:14:09,539 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 02:14:09,543 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4938
+INFO 2025-09-07 02:16:09,546 basehttp 77344 6157611008 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 02:16:09,549 basehttp 77344 6174437376 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4938
+INFO 2025-09-07 02:18:09,560 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 02:18:09,563 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4938
+INFO 2025-09-07 02:20:09,576 basehttp 77344 6157611008 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 02:20:09,578 basehttp 77344 6174437376 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4938
+INFO 2025-09-07 02:22:09,565 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 02:22:09,568 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4938
+INFO 2025-09-07 02:23:09,591 basehttp 77344 6157611008 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 02:23:09,594 basehttp 77344 6174437376 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4938
+INFO 2025-09-07 02:25:09,570 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 02:25:09,572 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4938
+INFO 2025-09-07 02:27:09,581 basehttp 77344 6157611008 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 02:27:09,585 basehttp 77344 6174437376 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4938
+INFO 2025-09-07 02:29:09,599 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 02:29:09,602 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4938
+INFO 2025-09-07 02:31:09,604 basehttp 77344 6157611008 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 02:31:09,607 basehttp 77344 6174437376 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4938
+INFO 2025-09-07 02:33:09,580 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 02:33:09,583 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4938
+INFO 2025-09-07 02:35:09,577 basehttp 77344 6157611008 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 02:35:09,580 basehttp 77344 6174437376 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4938
+INFO 2025-09-07 02:37:09,572 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 02:37:09,574 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4938
+INFO 2025-09-07 02:39:09,562 basehttp 77344 6157611008 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 02:39:09,564 basehttp 77344 6174437376 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4938
+INFO 2025-09-07 02:41:09,587 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 02:41:09,590 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4938
+INFO 2025-09-07 02:43:09,585 basehttp 77344 6157611008 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 02:43:09,589 basehttp 77344 6174437376 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4938
+INFO 2025-09-07 02:45:09,593 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 02:45:09,596 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4938
+INFO 2025-09-07 02:47:09,580 basehttp 77344 6157611008 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 02:47:09,583 basehttp 77344 6174437376 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4938
+INFO 2025-09-07 02:49:09,582 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 02:49:09,590 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4938
+INFO 2025-09-07 02:51:09,589 basehttp 77344 6157611008 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 02:51:09,592 basehttp 77344 6174437376 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4938
+INFO 2025-09-07 02:53:09,587 basehttp 77344 6157611008 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 02:53:09,590 basehttp 77344 6174437376 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4938
+INFO 2025-09-07 02:55:09,578 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 02:55:09,581 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4938
+INFO 2025-09-07 02:57:09,596 basehttp 77344 6157611008 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 02:57:09,600 basehttp 77344 6174437376 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4938
+INFO 2025-09-07 02:59:09,587 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 02:59:09,590 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4938
+INFO 2025-09-07 03:01:09,592 basehttp 77344 6157611008 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 03:01:09,596 basehttp 77344 6174437376 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 03:03:09,609 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 03:03:09,612 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 03:18:53,235 basehttp 77344 6157611008 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 03:18:53,238 basehttp 77344 6174437376 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 03:20:53,003 basehttp 77344 6157611008 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 03:20:53,007 basehttp 77344 6174437376 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 03:22:52,994 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 03:22:52,997 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 03:24:52,996 basehttp 77344 6157611008 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 03:24:52,999 basehttp 77344 6174437376 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 03:26:52,998 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 03:26:53,001 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 03:28:52,999 basehttp 77344 6157611008 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 03:28:53,002 basehttp 77344 6174437376 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 03:30:53,015 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 03:30:53,018 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 03:32:53,011 basehttp 77344 6157611008 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 03:32:53,015 basehttp 77344 6174437376 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 03:34:52,851 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 03:34:52,854 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 03:36:52,849 basehttp 77344 6157611008 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 03:36:52,852 basehttp 77344 6174437376 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 03:38:52,848 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 03:38:52,851 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 03:40:52,845 basehttp 77344 6157611008 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 03:40:52,848 basehttp 77344 6174437376 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 03:42:52,858 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 03:42:52,861 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 03:44:52,844 basehttp 77344 6157611008 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 03:44:52,847 basehttp 77344 6174437376 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 03:46:52,845 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 03:46:52,847 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 03:48:52,841 basehttp 77344 6157611008 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 03:48:52,844 basehttp 77344 6174437376 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 03:50:52,847 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 03:50:52,850 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 03:52:52,839 basehttp 77344 6157611008 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 03:52:52,845 basehttp 77344 6174437376 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 03:54:52,845 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 03:54:52,848 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 03:56:52,852 basehttp 77344 6157611008 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 03:56:52,855 basehttp 77344 6174437376 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 03:58:52,844 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 03:58:52,847 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 04:00:52,843 basehttp 77344 6157611008 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 04:00:52,845 basehttp 77344 6174437376 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 04:02:52,842 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 04:02:52,845 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 04:04:52,855 basehttp 77344 6157611008 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 04:04:52,858 basehttp 77344 6174437376 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 04:06:52,858 basehttp 77344 6157611008 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 04:06:52,861 basehttp 77344 6174437376 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 04:08:52,847 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 04:08:52,850 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 04:10:52,846 basehttp 77344 6157611008 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 04:10:52,849 basehttp 77344 6174437376 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 04:12:52,845 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 04:12:52,849 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 04:14:52,844 basehttp 77344 6157611008 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 04:14:52,847 basehttp 77344 6174437376 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 04:16:52,851 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 04:16:52,854 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 04:18:52,841 basehttp 77344 6157611008 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 04:18:52,843 basehttp 77344 6174437376 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 04:27:01,087 basehttp 77344 6157611008 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 04:27:01,090 basehttp 77344 6174437376 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 04:30:06,007 basehttp 77344 6157611008 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 04:30:06,010 basehttp 77344 6174437376 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 04:45:08,671 basehttp 77344 6157611008 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 04:45:08,674 basehttp 77344 6174437376 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 04:46:08,658 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 04:47:08,668 basehttp 77344 6174437376 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 04:48:08,647 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 04:49:08,665 basehttp 77344 6174437376 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 04:50:08,655 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 04:51:08,672 basehttp 77344 6174437376 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 04:52:08,658 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 04:53:08,660 basehttp 77344 6174437376 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 04:54:08,641 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 04:55:08,659 basehttp 77344 6174437376 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 04:56:08,659 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 04:57:08,646 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 04:58:08,641 basehttp 77344 6157611008 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 04:59:08,640 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 05:00:08,644 basehttp 77344 6157611008 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 05:01:08,639 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 05:02:08,674 basehttp 77344 6157611008 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 05:03:08,634 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 05:04:08,637 basehttp 77344 6157611008 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 05:05:08,632 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 05:06:08,645 basehttp 77344 6157611008 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 05:07:08,641 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 05:08:08,627 basehttp 77344 6157611008 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 05:09:08,643 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 05:10:08,646 basehttp 77344 6157611008 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 05:11:08,624 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 05:12:08,627 basehttp 77344 6157611008 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 05:13:08,645 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 05:14:08,627 basehttp 77344 6157611008 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 05:15:08,630 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 05:16:08,632 basehttp 77344 6157611008 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 05:17:08,663 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 05:18:08,638 basehttp 77344 6157611008 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 05:19:08,628 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 05:20:08,638 basehttp 77344 6157611008 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 05:21:08,649 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 05:22:08,631 basehttp 77344 6157611008 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 05:23:08,635 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 05:24:08,637 basehttp 77344 6157611008 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 05:25:08,624 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 05:26:08,621 basehttp 77344 6157611008 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 05:27:08,627 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 05:28:08,661 basehttp 77344 6157611008 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 05:28:08,664 basehttp 77344 6174437376 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 05:30:08,620 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 05:30:08,622 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 05:31:08,737 basehttp 77344 6157611008 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 05:32:08,740 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 05:33:08,735 basehttp 77344 6157611008 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 05:34:08,753 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 05:35:08,751 basehttp 77344 6157611008 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 05:36:08,739 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 05:37:08,741 basehttp 77344 6157611008 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 05:38:08,756 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 05:39:08,748 basehttp 77344 6157611008 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 05:40:08,756 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 05:41:08,739 basehttp 77344 6157611008 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 05:42:08,746 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 05:43:08,753 basehttp 77344 6157611008 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 05:44:08,741 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 05:45:08,754 basehttp 77344 6157611008 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 05:48:49,254 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 05:51:47,792 basehttp 77344 6157611008 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 05:56:57,168 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 05:57:57,160 basehttp 77344 6157611008 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 05:58:57,173 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 05:59:57,161 basehttp 77344 6157611008 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 06:00:57,166 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 06:01:57,162 basehttp 77344 6157611008 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 06:02:57,164 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 06:03:57,148 basehttp 77344 6157611008 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 06:04:57,152 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 06:05:57,149 basehttp 77344 6157611008 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 06:06:57,148 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 06:07:57,147 basehttp 77344 6157611008 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 06:08:57,151 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 06:09:57,151 basehttp 77344 6157611008 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 06:10:57,151 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 06:11:57,147 basehttp 77344 6157611008 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 06:12:57,150 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 06:13:57,149 basehttp 77344 6157611008 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 06:14:57,149 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 06:15:57,139 basehttp 77344 6157611008 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 06:16:57,153 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 06:17:57,147 basehttp 77344 6157611008 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 06:18:57,160 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 06:19:57,165 basehttp 77344 6157611008 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 06:20:57,163 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 06:21:57,158 basehttp 77344 6157611008 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 06:22:57,161 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 06:23:57,160 basehttp 77344 6157611008 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 06:24:57,170 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 06:25:57,158 basehttp 77344 6157611008 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 06:26:57,162 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 06:27:57,160 basehttp 77344 6157611008 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 06:28:57,152 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 06:29:57,168 basehttp 77344 6157611008 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 06:30:57,148 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 06:31:57,158 basehttp 77344 6157611008 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 06:32:57,162 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 06:33:57,170 basehttp 77344 6157611008 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 06:34:57,172 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 06:35:57,172 basehttp 77344 6157611008 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 06:36:57,172 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 06:37:57,172 basehttp 77344 6157611008 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 06:38:57,171 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 06:39:57,179 basehttp 77344 6157611008 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 06:40:57,175 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 06:41:57,172 basehttp 77344 6157611008 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 06:42:57,175 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 06:43:57,163 basehttp 77344 6157611008 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 06:44:57,171 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 06:45:57,172 basehttp 77344 6157611008 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 06:46:57,177 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 06:47:57,174 basehttp 77344 6157611008 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 06:48:57,302 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 06:49:57,308 basehttp 77344 6157611008 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 06:50:57,305 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 06:51:57,303 basehttp 77344 6157611008 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 06:52:57,307 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 06:53:57,308 basehttp 77344 6157611008 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 06:54:57,308 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 06:55:57,308 basehttp 77344 6157611008 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 07:00:31,574 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 07:04:05,986 basehttp 77344 6157611008 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 07:07:02,629 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 07:10:49,009 basehttp 77344 6157611008 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 07:11:48,997 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 07:12:49,000 basehttp 77344 6157611008 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 07:13:49,030 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 07:13:49,030 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 07:15:48,889 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 07:15:48,893 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 07:17:48,887 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 07:17:48,889 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 07:19:48,882 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 07:19:48,884 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 07:20:48,897 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 07:20:48,900 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 07:22:48,882 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 07:22:48,884 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 07:24:48,877 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 07:24:48,879 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 07:26:48,890 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 07:26:48,893 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 07:28:48,885 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 07:28:48,889 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 07:30:48,884 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 07:30:48,888 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 07:32:48,916 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 07:32:48,918 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 07:34:48,892 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 07:34:48,894 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 07:36:48,888 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 07:36:48,891 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 07:38:48,891 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 07:38:48,895 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 07:40:48,889 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 07:40:48,892 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 07:42:48,882 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 07:42:48,885 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 07:44:48,900 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 07:44:48,903 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 07:46:48,771 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 07:46:48,774 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 07:48:48,772 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 07:48:48,773 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 07:50:48,784 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 07:50:48,785 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 07:52:48,777 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 07:52:48,780 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 07:53:48,801 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 07:53:48,803 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 07:55:48,784 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 07:55:48,787 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 07:57:48,761 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 07:57:48,764 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 07:59:48,762 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 07:59:48,765 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 08:01:48,761 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 08:01:48,764 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 08:03:48,754 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 08:03:48,756 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 08:05:48,760 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 08:05:48,763 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 08:07:48,749 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 08:07:48,751 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 08:08:48,741 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 08:08:48,743 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 08:10:48,745 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 08:10:48,747 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 08:14:35,707 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 08:14:35,710 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 08:22:57,062 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 08:22:57,065 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 08:24:57,051 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 08:24:57,055 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 08:26:57,052 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 08:26:57,055 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 08:28:57,050 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 08:28:57,053 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 08:30:57,047 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 08:30:57,050 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 08:36:20,741 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 08:36:20,744 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 08:38:20,730 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 08:38:20,733 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 08:40:20,727 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 08:40:20,730 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 08:42:20,735 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 08:42:20,738 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 08:44:20,723 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 08:44:20,726 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 08:46:20,729 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 08:46:20,733 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 08:48:20,725 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 08:48:20,729 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 08:50:20,833 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 08:50:20,836 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 08:52:20,836 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 08:52:20,839 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 08:54:20,821 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 08:54:20,823 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 08:56:20,846 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 08:56:20,848 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 08:58:20,838 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 08:58:20,843 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 09:00:20,836 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 09:00:20,838 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 09:02:20,836 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 09:02:20,839 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 09:04:20,836 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 09:04:20,838 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 09:06:20,831 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 09:06:20,834 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 09:08:20,841 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 09:08:20,845 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 09:10:20,835 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 09:10:20,838 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 09:12:20,835 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 09:12:20,838 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 09:14:20,871 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 09:14:20,873 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 09:16:20,815 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 09:16:20,817 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 09:18:20,843 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 09:18:20,846 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 09:20:20,933 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 09:20:20,935 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 09:22:20,970 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 09:22:20,972 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 09:24:20,938 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 09:24:20,941 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 09:26:20,941 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 09:26:20,944 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 09:28:20,955 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 09:28:20,959 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 09:30:20,943 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 09:30:20,945 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 09:32:20,947 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 09:32:20,950 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 09:34:20,950 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 09:34:20,952 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 09:43:12,980 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 09:43:12,985 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 09:44:12,941 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 09:44:12,943 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 09:45:12,948 basehttp 77344 6157611008 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 09:45:12,951 basehttp 77344 6174437376 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 09:46:12,953 basehttp 77344 6157611008 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 09:46:12,956 basehttp 77344 6174437376 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 09:47:13,815 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 09:47:13,817 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 09:52:52,859 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 09:52:52,861 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 09:57:54,394 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 09:57:54,397 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 09:59:54,393 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 09:59:54,396 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 10:08:09,558 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 10:08:09,561 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 10:10:09,559 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 10:10:09,562 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 10:12:09,559 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 10:12:09,562 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 10:14:09,566 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 10:14:09,569 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 10:16:09,571 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 10:16:09,573 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 10:18:09,578 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 10:18:09,582 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 10:20:09,568 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 10:20:09,570 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 10:22:09,571 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 10:22:09,574 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 10:24:09,572 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 10:24:09,574 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 10:26:09,567 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 10:26:09,569 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 10:28:09,574 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 10:28:09,577 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 10:30:09,584 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 10:30:09,587 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 10:32:09,578 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 10:32:09,581 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 10:34:09,563 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 10:34:09,574 basehttp 77344 6157611008 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 10:36:09,576 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 10:36:09,580 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 10:38:09,576 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 10:38:09,579 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 10:40:09,628 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 10:40:09,631 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 10:42:09,622 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 10:42:09,624 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 10:44:09,630 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 10:44:09,633 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 10:46:09,633 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 10:46:09,636 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 10:48:09,629 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 10:48:09,632 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 10:50:09,638 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 10:50:09,640 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 10:52:09,641 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 10:52:09,644 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 10:54:09,638 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 10:54:09,640 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 10:56:09,641 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 10:56:09,643 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 10:58:09,649 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 10:58:09,652 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 11:00:09,659 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 11:00:09,662 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 11:02:09,646 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 11:02:09,650 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 11:04:09,654 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 11:04:09,657 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 11:06:09,661 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 11:06:09,664 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 11:08:09,654 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 11:08:09,657 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 11:18:47,301 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 11:18:47,303 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 11:26:17,718 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 11:26:17,721 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 11:33:46,852 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 11:33:46,854 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 11:46:00,804 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 11:46:00,806 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 11:48:00,816 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 11:48:00,818 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 11:50:00,816 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 11:50:00,818 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 11:52:00,817 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 11:52:00,819 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 11:54:00,814 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 11:54:00,817 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 11:56:00,825 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 11:56:00,827 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 11:58:00,832 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 11:58:00,835 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 12:00:00,834 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 12:00:00,837 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 12:02:00,850 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 12:02:00,853 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 12:04:00,853 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 12:04:00,856 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 12:06:00,860 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 12:06:00,863 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 12:08:00,856 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 12:08:00,859 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 12:10:00,855 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 12:10:00,858 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 12:29:03,105 basehttp 77344 6157611008 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+INFO 2025-09-07 12:29:03,107 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+WARNING 2025-09-07 12:29:05,278 log 77344 6174437376 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 12:29:05,278 basehttp 77344 6174437376 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+WARNING 2025-09-07 12:29:06,347 log 77344 6174437376 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 12:29:06,347 basehttp 77344 6174437376 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+WARNING 2025-09-07 12:29:07,590 log 77344 6174437376 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 12:29:07,591 basehttp 77344 6174437376 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+WARNING 2025-09-07 12:29:07,602 log 77344 6174437376 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 12:29:07,602 basehttp 77344 6174437376 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-07 12:30:05,385 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 12:31:05,382 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 12:32:05,383 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 12:33:05,384 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 12:34:05,402 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 12:34:22,538 basehttp 77344 6174437376 "GET /en/billing/bills/create/ HTTP/1.1" 200 126347
+WARNING 2025-09-07 12:34:22,558 log 77344 6174437376 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 12:34:22,558 basehttp 77344 6174437376 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-07 12:34:22,607 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 12:35:22,623 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+WARNING 2025-09-07 12:35:40,628 log 77344 6208090112 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 12:35:40,629 basehttp 77344 6208090112 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-07 12:35:40,632 basehttp 77344 6157611008 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 12:35:40,635 basehttp 77344 6191263744 "GET /en/htmx/system-health/ HTTP/1.1" 200 1356
+INFO 2025-09-07 12:35:40,638 basehttp 77344 6174437376 "GET /en/htmx/dashboard-stats/ HTTP/1.1" 200 2094
+WARNING 2025-09-07 12:35:40,641 log 77344 6208090112 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 12:35:40,641 basehttp 77344 6208090112 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-07 12:35:46,410 basehttp 77344 6208090112 "GET /en/billing HTTP/1.1" 301 0
+INFO 2025-09-07 12:35:46,434 basehttp 77344 6174437376 "GET /en/billing/ HTTP/1.1" 200 47086
+WARNING 2025-09-07 12:35:46,448 log 77344 6174437376 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 12:35:46,449 basehttp 77344 6174437376 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-07 12:35:46,477 basehttp 77344 6174437376 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 12:35:46,480 basehttp 77344 6191263744 "GET /en/billing/htmx/stats/ HTTP/1.1" 200 4943
+ERROR 2025-09-07 12:35:53,457 log 77344 6191263744 Internal Server Error: /en/billing/claims/
+Traceback (most recent call last):
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/core/handlers/exception.py", line 55, in inner
+ response = get_response(request)
+ ^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/core/handlers/base.py", line 220, in _get_response
+ response = response.render()
+ ^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/response.py", line 114, in render
+ self.content = self.rendered_content
+ ^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/response.py", line 92, in rendered_content
+ return template.render(context, self._request)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/backends/django.py", line 107, in render
+ return self.template.render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 171, in render
+ return self._render(context)
+ ^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 163, in _render
+ return self.nodelist.render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 1016, in render
+ return SafeString("".join([node.render_annotated(context) for node in self]))
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 977, in render_annotated
+ return self.render(context)
+ ^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/loader_tags.py", line 159, in render
+ return compiled_parent._render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 163, in _render
+ return self.nodelist.render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 1016, in render
+ return SafeString("".join([node.render_annotated(context) for node in self]))
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 977, in render_annotated
+ return self.render(context)
+ ^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/loader_tags.py", line 65, in render
+ result = block.nodelist.render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 1016, in render
+ return SafeString("".join([node.render_annotated(context) for node in self]))
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 977, in render_annotated
+ return self.render(context)
+ ^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/defaulttags.py", line 480, in render
+ url = reverse(view_name, args=args, kwargs=kwargs, current_app=current_app)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/urls/base.py", line 98, in reverse
+ resolved_url = resolver._reverse_with_prefix(view, prefix, *args, **kwargs)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/urls/resolvers.py", line 831, in _reverse_with_prefix
+ raise NoReverseMatch(msg)
+django.urls.exceptions.NoReverseMatch: Reverse for 'export_claims' not found. 'export_claims' is not a valid view function or pattern name.
+ERROR 2025-09-07 12:35:53,458 basehttp 77344 6191263744 "GET /en/billing/claims/ HTTP/1.1" 500 207751
+WARNING 2025-09-07 12:35:53,477 log 77344 6191263744 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 12:35:53,477 basehttp 77344 6191263744 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-07 12:39:36,305 autoreload 77344 8747049152 /Users/marwanalwali/manus_project/hospital_management_system_v4/billing/views.py changed, reloading.
+INFO 2025-09-07 12:39:36,788 autoreload 97928 8747049152 Watching for file changes with StatReloader
+INFO 2025-09-07 12:40:53,033 autoreload 97928 8747049152 /Users/marwanalwali/manus_project/hospital_management_system_v4/billing/views.py changed, reloading.
+INFO 2025-09-07 12:40:53,426 autoreload 98481 8747049152 Watching for file changes with StatReloader
+ERROR 2025-09-07 12:40:54,795 log 98481 6134345728 Internal Server Error: /en/billing/claims/
+Traceback (most recent call last):
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/core/handlers/exception.py", line 55, in inner
+ response = get_response(request)
+ ^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/core/handlers/base.py", line 220, in _get_response
+ response = response.render()
+ ^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/response.py", line 114, in render
+ self.content = self.rendered_content
+ ^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/response.py", line 92, in rendered_content
+ return template.render(context, self._request)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/backends/django.py", line 107, in render
+ return self.template.render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 171, in render
+ return self._render(context)
+ ^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 163, in _render
+ return self.nodelist.render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 1016, in render
+ return SafeString("".join([node.render_annotated(context) for node in self]))
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 977, in render_annotated
+ return self.render(context)
+ ^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/loader_tags.py", line 159, in render
+ return compiled_parent._render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 163, in _render
+ return self.nodelist.render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 1016, in render
+ return SafeString("".join([node.render_annotated(context) for node in self]))
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 977, in render_annotated
+ return self.render(context)
+ ^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/loader_tags.py", line 65, in render
+ result = block.nodelist.render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 1016, in render
+ return SafeString("".join([node.render_annotated(context) for node in self]))
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 977, in render_annotated
+ return self.render(context)
+ ^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/defaulttags.py", line 480, in render
+ url = reverse(view_name, args=args, kwargs=kwargs, current_app=current_app)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/urls/base.py", line 98, in reverse
+ resolved_url = resolver._reverse_with_prefix(view, prefix, *args, **kwargs)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/urls/resolvers.py", line 831, in _reverse_with_prefix
+ raise NoReverseMatch(msg)
+django.urls.exceptions.NoReverseMatch: Reverse for 'export_claims' not found. 'export_claims' is not a valid view function or pattern name.
+ERROR 2025-09-07 12:40:54,797 basehttp 98481 6134345728 "GET /en/billing/claims/ HTTP/1.1" 500 207888
+WARNING 2025-09-07 12:40:54,809 log 98481 6134345728 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 12:40:54,809 basehttp 98481 6134345728 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-07 12:44:58,267 autoreload 98481 8747049152 /Users/marwanalwali/manus_project/hospital_management_system_v4/billing/views.py changed, reloading.
+INFO 2025-09-07 12:44:58,602 autoreload 826 8747049152 Watching for file changes with StatReloader
+INFO 2025-09-07 12:45:22,581 autoreload 826 8747049152 /Users/marwanalwali/manus_project/hospital_management_system_v4/billing/urls.py changed, reloading.
+INFO 2025-09-07 12:45:22,898 autoreload 1126 8747049152 Watching for file changes with StatReloader
+ERROR 2025-09-07 12:45:24,934 log 1126 6129577984 Internal Server Error: /en/billing/claims/
+Traceback (most recent call last):
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/core/handlers/exception.py", line 55, in inner
+ response = get_response(request)
+ ^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/core/handlers/base.py", line 220, in _get_response
+ response = response.render()
+ ^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/response.py", line 114, in render
+ self.content = self.rendered_content
+ ^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/response.py", line 92, in rendered_content
+ return template.render(context, self._request)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/backends/django.py", line 107, in render
+ return self.template.render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 171, in render
+ return self._render(context)
+ ^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 163, in _render
+ return self.nodelist.render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 1016, in render
+ return SafeString("".join([node.render_annotated(context) for node in self]))
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 977, in render_annotated
+ return self.render(context)
+ ^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/loader_tags.py", line 159, in render
+ return compiled_parent._render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 163, in _render
+ return self.nodelist.render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 1016, in render
+ return SafeString("".join([node.render_annotated(context) for node in self]))
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 977, in render_annotated
+ return self.render(context)
+ ^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/loader_tags.py", line 65, in render
+ result = block.nodelist.render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 1016, in render
+ return SafeString("".join([node.render_annotated(context) for node in self]))
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 977, in render_annotated
+ return self.render(context)
+ ^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/defaulttags.py", line 480, in render
+ url = reverse(view_name, args=args, kwargs=kwargs, current_app=current_app)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/urls/base.py", line 98, in reverse
+ resolved_url = resolver._reverse_with_prefix(view, prefix, *args, **kwargs)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/urls/resolvers.py", line 831, in _reverse_with_prefix
+ raise NoReverseMatch(msg)
+django.urls.exceptions.NoReverseMatch: Reverse for 'batch_submit_claims' not found. 'batch_submit_claims' is not a valid view function or pattern name.
+ERROR 2025-09-07 12:45:24,936 basehttp 1126 6129577984 "GET /en/billing/claims/ HTTP/1.1" 500 207934
+WARNING 2025-09-07 12:45:24,952 log 1126 6129577984 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 12:45:24,952 basehttp 1126 6129577984 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+ERROR 2025-09-07 12:45:46,751 log 1126 6129577984 Internal Server Error: /en/billing/claims/
+Traceback (most recent call last):
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/core/handlers/exception.py", line 55, in inner
+ response = get_response(request)
+ ^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/core/handlers/base.py", line 220, in _get_response
+ response = response.render()
+ ^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/response.py", line 114, in render
+ self.content = self.rendered_content
+ ^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/response.py", line 92, in rendered_content
+ return template.render(context, self._request)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/backends/django.py", line 107, in render
+ return self.template.render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 171, in render
+ return self._render(context)
+ ^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 163, in _render
+ return self.nodelist.render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 1016, in render
+ return SafeString("".join([node.render_annotated(context) for node in self]))
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 977, in render_annotated
+ return self.render(context)
+ ^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/loader_tags.py", line 159, in render
+ return compiled_parent._render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 163, in _render
+ return self.nodelist.render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 1016, in render
+ return SafeString("".join([node.render_annotated(context) for node in self]))
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 977, in render_annotated
+ return self.render(context)
+ ^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/loader_tags.py", line 65, in render
+ result = block.nodelist.render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 1016, in render
+ return SafeString("".join([node.render_annotated(context) for node in self]))
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 977, in render_annotated
+ return self.render(context)
+ ^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/defaulttags.py", line 480, in render
+ url = reverse(view_name, args=args, kwargs=kwargs, current_app=current_app)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/urls/base.py", line 98, in reverse
+ resolved_url = resolver._reverse_with_prefix(view, prefix, *args, **kwargs)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/urls/resolvers.py", line 831, in _reverse_with_prefix
+ raise NoReverseMatch(msg)
+django.urls.exceptions.NoReverseMatch: Reverse for 'claim_stats' not found. 'claim_stats' is not a valid view function or pattern name.
+ERROR 2025-09-07 12:45:46,753 basehttp 1126 6129577984 "GET /en/billing/claims/ HTTP/1.1" 500 207076
+WARNING 2025-09-07 12:45:46,769 log 1126 6129577984 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 12:45:46,770 basehttp 1126 6129577984 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+ERROR 2025-09-07 12:46:13,557 log 1126 6129577984 Internal Server Error: /en/billing/claims/
+Traceback (most recent call last):
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/core/handlers/exception.py", line 55, in inner
+ response = get_response(request)
+ ^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/core/handlers/base.py", line 220, in _get_response
+ response = response.render()
+ ^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/response.py", line 114, in render
+ self.content = self.rendered_content
+ ^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/response.py", line 92, in rendered_content
+ return template.render(context, self._request)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/backends/django.py", line 107, in render
+ return self.template.render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 171, in render
+ return self._render(context)
+ ^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 163, in _render
+ return self.nodelist.render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 1016, in render
+ return SafeString("".join([node.render_annotated(context) for node in self]))
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 977, in render_annotated
+ return self.render(context)
+ ^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/loader_tags.py", line 159, in render
+ return compiled_parent._render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 163, in _render
+ return self.nodelist.render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 1016, in render
+ return SafeString("".join([node.render_annotated(context) for node in self]))
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 977, in render_annotated
+ return self.render(context)
+ ^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/loader_tags.py", line 65, in render
+ result = block.nodelist.render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 1016, in render
+ return SafeString("".join([node.render_annotated(context) for node in self]))
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 977, in render_annotated
+ return self.render(context)
+ ^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/defaulttags.py", line 243, in render
+ nodelist.append(node.render_annotated(context))
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 977, in render_annotated
+ return self.render(context)
+ ^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/defaulttags.py", line 480, in render
+ url = reverse(view_name, args=args, kwargs=kwargs, current_app=current_app)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/urls/base.py", line 98, in reverse
+ resolved_url = resolver._reverse_with_prefix(view, prefix, *args, **kwargs)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/urls/resolvers.py", line 831, in _reverse_with_prefix
+ raise NoReverseMatch(msg)
+django.urls.exceptions.NoReverseMatch: Reverse for 'claim_print' not found. 'claim_print' is not a valid view function or pattern name.
+ERROR 2025-09-07 12:46:13,558 basehttp 1126 6129577984 "GET /en/billing/claims/ HTTP/1.1" 500 236107
+WARNING 2025-09-07 12:46:13,574 log 1126 6129577984 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 12:46:13,574 basehttp 1126 6129577984 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+ERROR 2025-09-07 12:46:55,322 log 1126 6129577984 Internal Server Error: /en/billing/claims/
+Traceback (most recent call last):
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/core/handlers/exception.py", line 55, in inner
+ response = get_response(request)
+ ^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/core/handlers/base.py", line 220, in _get_response
+ response = response.render()
+ ^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/response.py", line 114, in render
+ self.content = self.rendered_content
+ ^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/response.py", line 92, in rendered_content
+ return template.render(context, self._request)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/backends/django.py", line 107, in render
+ return self.template.render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 171, in render
+ return self._render(context)
+ ^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 163, in _render
+ return self.nodelist.render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 1016, in render
+ return SafeString("".join([node.render_annotated(context) for node in self]))
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 977, in render_annotated
+ return self.render(context)
+ ^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/loader_tags.py", line 159, in render
+ return compiled_parent._render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 163, in _render
+ return self.nodelist.render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 1016, in render
+ return SafeString("".join([node.render_annotated(context) for node in self]))
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 977, in render_annotated
+ return self.render(context)
+ ^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/loader_tags.py", line 65, in render
+ result = block.nodelist.render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 1016, in render
+ return SafeString("".join([node.render_annotated(context) for node in self]))
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 977, in render_annotated
+ return self.render(context)
+ ^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/defaulttags.py", line 480, in render
+ url = reverse(view_name, args=args, kwargs=kwargs, current_app=current_app)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/urls/base.py", line 98, in reverse
+ resolved_url = resolver._reverse_with_prefix(view, prefix, *args, **kwargs)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/urls/resolvers.py", line 831, in _reverse_with_prefix
+ raise NoReverseMatch(msg)
+django.urls.exceptions.NoReverseMatch: Reverse for 'bulk_submit_claims' not found. 'bulk_submit_claims' is not a valid view function or pattern name.
+ERROR 2025-09-07 12:46:55,324 basehttp 1126 6129577984 "GET /en/billing/claims/ HTTP/1.1" 500 211156
+WARNING 2025-09-07 12:46:55,339 log 1126 6129577984 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 12:46:55,339 basehttp 1126 6129577984 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-07 12:47:18,798 basehttp 1126 6129577984 "GET /en/billing/claims/ HTTP/1.1" 200 144975
+WARNING 2025-09-07 12:47:18,815 log 1126 6129577984 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 12:47:18,815 basehttp 1126 6129577984 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-07 12:47:18,892 basehttp 1126 6129577984 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 12:48:05,593 basehttp 1126 6129577984 "GET /en/billing/claims/ HTTP/1.1" 200 145155
+WARNING 2025-09-07 12:48:05,607 log 1126 6129577984 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 12:48:05,608 basehttp 1126 6129577984 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-07 12:48:05,660 basehttp 1126 6129577984 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 12:48:17,864 basehttp 1126 6129577984 "GET /en/billing/claims/172084ad-de1a-44f4-b67d-f89f27dca7dc/ HTTP/1.1" 200 37650
+WARNING 2025-09-07 12:48:17,881 log 1126 6129577984 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 12:48:17,882 basehttp 1126 6129577984 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-07 12:48:17,924 basehttp 1126 6129577984 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+WARNING 2025-09-07 12:48:28,251 log 1126 6129577984 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 12:48:28,251 basehttp 1126 6129577984 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+WARNING 2025-09-07 12:48:28,285 log 1126 6129577984 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 12:48:28,286 basehttp 1126 6129577984 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-07 12:49:05,672 basehttp 1126 6129577984 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 12:49:20,467 autoreload 1126 8747049152 /Users/marwanalwali/manus_project/hospital_management_system_v4/billing/views.py changed, reloading.
+INFO 2025-09-07 12:49:20,872 autoreload 2864 8747049152 Watching for file changes with StatReloader
+WARNING 2025-09-07 12:49:21,914 log 2864 6203011072 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 12:49:21,914 basehttp 2864 6203011072 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+WARNING 2025-09-07 12:49:21,927 log 2864 6203011072 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 12:49:21,927 basehttp 2864 6203011072 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-07 12:49:22,778 basehttp 2864 6203011072 "GET /en/billing/claims/ HTTP/1.1" 200 145155
+WARNING 2025-09-07 12:49:22,799 log 2864 6203011072 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 12:49:22,799 basehttp 2864 6203011072 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-07 12:49:22,857 basehttp 2864 6203011072 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+ERROR 2025-09-07 12:49:24,049 log 2864 6203011072 Internal Server Error: /en/billing/claims/create/
+Traceback (most recent call last):
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/core/handlers/exception.py", line 55, in inner
+ response = get_response(request)
+ ^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/core/handlers/base.py", line 220, in _get_response
+ response = response.render()
+ ^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/response.py", line 114, in render
+ self.content = self.rendered_content
+ ^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/response.py", line 92, in rendered_content
+ return template.render(context, self._request)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/backends/django.py", line 107, in render
+ return self.template.render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 171, in render
+ return self._render(context)
+ ^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 163, in _render
+ return self.nodelist.render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 1016, in render
+ return SafeString("".join([node.render_annotated(context) for node in self]))
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 977, in render_annotated
+ return self.render(context)
+ ^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/loader_tags.py", line 159, in render
+ return compiled_parent._render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 163, in _render
+ return self.nodelist.render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 1016, in render
+ return SafeString("".join([node.render_annotated(context) for node in self]))
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 977, in render_annotated
+ return self.render(context)
+ ^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/loader_tags.py", line 65, in render
+ result = block.nodelist.render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 1016, in render
+ return SafeString("".join([node.render_annotated(context) for node in self]))
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 977, in render_annotated
+ return self.render(context)
+ ^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/defaulttags.py", line 480, in render
+ url = reverse(view_name, args=args, kwargs=kwargs, current_app=current_app)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/urls/base.py", line 98, in reverse
+ resolved_url = resolver._reverse_with_prefix(view, prefix, *args, **kwargs)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/urls/resolvers.py", line 831, in _reverse_with_prefix
+ raise NoReverseMatch(msg)
+django.urls.exceptions.NoReverseMatch: Reverse for 'bill_details_api' not found. 'bill_details_api' is not a valid view function or pattern name.
+ERROR 2025-09-07 12:49:24,051 basehttp 2864 6203011072 "GET /en/billing/claims/create/ HTTP/1.1" 500 194122
+WARNING 2025-09-07 12:49:24,068 log 2864 6203011072 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 12:49:24,068 basehttp 2864 6203011072 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-07 14:02:57,501 autoreload 2864 8747049152 /Users/marwanalwali/manus_project/hospital_management_system_v4/billing/urls.py changed, reloading.
+INFO 2025-09-07 14:02:58,023 autoreload 5063 8747049152 Watching for file changes with StatReloader
+INFO 2025-09-07 14:07:44,147 autoreload 5063 8747049152 /Users/marwanalwali/manus_project/hospital_management_system_v4/billing/urls.py changed, reloading.
+INFO 2025-09-07 14:07:44,460 autoreload 7139 8747049152 Watching for file changes with StatReloader
+ERROR 2025-09-07 14:07:46,904 log 7139 6202322944 Internal Server Error: /en/billing/claims/create/
+Traceback (most recent call last):
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/core/handlers/exception.py", line 55, in inner
+ response = get_response(request)
+ ^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/core/handlers/base.py", line 220, in _get_response
+ response = response.render()
+ ^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/response.py", line 114, in render
+ self.content = self.rendered_content
+ ^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/response.py", line 92, in rendered_content
+ return template.render(context, self._request)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/backends/django.py", line 107, in render
+ return self.template.render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 171, in render
+ return self._render(context)
+ ^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 163, in _render
+ return self.nodelist.render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 1016, in render
+ return SafeString("".join([node.render_annotated(context) for node in self]))
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 977, in render_annotated
+ return self.render(context)
+ ^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/loader_tags.py", line 159, in render
+ return compiled_parent._render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 163, in _render
+ return self.nodelist.render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 1016, in render
+ return SafeString("".join([node.render_annotated(context) for node in self]))
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 977, in render_annotated
+ return self.render(context)
+ ^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/loader_tags.py", line 65, in render
+ result = block.nodelist.render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 1016, in render
+ return SafeString("".join([node.render_annotated(context) for node in self]))
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 977, in render_annotated
+ return self.render(context)
+ ^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/defaulttags.py", line 480, in render
+ url = reverse(view_name, args=args, kwargs=kwargs, current_app=current_app)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/urls/base.py", line 98, in reverse
+ resolved_url = resolver._reverse_with_prefix(view, prefix, *args, **kwargs)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/urls/resolvers.py", line 831, in _reverse_with_prefix
+ raise NoReverseMatch(msg)
+django.urls.exceptions.NoReverseMatch: Reverse for 'bill_details_api' with no arguments not found. 1 pattern(s) tried: ['en/billing/bills/(?P[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})/\\Z']
+ERROR 2025-09-07 14:07:46,906 basehttp 7139 6202322944 "GET /en/billing/claims/create/ HTTP/1.1" 500 196668
+WARNING 2025-09-07 14:07:46,924 log 7139 6202322944 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 14:07:46,924 basehttp 7139 6202322944 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+ERROR 2025-09-07 14:09:34,737 log 7139 6202322944 Internal Server Error: /en/billing/claims/create/
+Traceback (most recent call last):
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/core/handlers/exception.py", line 55, in inner
+ response = get_response(request)
+ ^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/core/handlers/base.py", line 220, in _get_response
+ response = response.render()
+ ^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/response.py", line 114, in render
+ self.content = self.rendered_content
+ ^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/response.py", line 92, in rendered_content
+ return template.render(context, self._request)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/backends/django.py", line 107, in render
+ return self.template.render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 171, in render
+ return self._render(context)
+ ^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 163, in _render
+ return self.nodelist.render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 1016, in render
+ return SafeString("".join([node.render_annotated(context) for node in self]))
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 977, in render_annotated
+ return self.render(context)
+ ^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/loader_tags.py", line 159, in render
+ return compiled_parent._render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 163, in _render
+ return self.nodelist.render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 1016, in render
+ return SafeString("".join([node.render_annotated(context) for node in self]))
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 977, in render_annotated
+ return self.render(context)
+ ^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/loader_tags.py", line 65, in render
+ result = block.nodelist.render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 1016, in render
+ return SafeString("".join([node.render_annotated(context) for node in self]))
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 977, in render_annotated
+ return self.render(context)
+ ^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/defaulttags.py", line 480, in render
+ url = reverse(view_name, args=args, kwargs=kwargs, current_app=current_app)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/urls/base.py", line 98, in reverse
+ resolved_url = resolver._reverse_with_prefix(view, prefix, *args, **kwargs)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/urls/resolvers.py", line 831, in _reverse_with_prefix
+ raise NoReverseMatch(msg)
+django.urls.exceptions.NoReverseMatch: Reverse for 'bill_details_api' with arguments '('',)' not found. 1 pattern(s) tried: ['en/billing/bills/(?P[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})/\\Z']
+ERROR 2025-09-07 14:09:34,739 basehttp 7139 6202322944 "GET /en/billing/claims/create/ HTTP/1.1" 500 198113
+WARNING 2025-09-07 14:09:34,753 log 7139 6202322944 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 14:09:34,753 basehttp 7139 6202322944 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+ERROR 2025-09-07 14:10:56,880 log 7139 6202322944 Internal Server Error: /en/billing/claims/create/
+Traceback (most recent call last):
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/core/handlers/exception.py", line 55, in inner
+ response = get_response(request)
+ ^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/core/handlers/base.py", line 220, in _get_response
+ response = response.render()
+ ^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/response.py", line 114, in render
+ self.content = self.rendered_content
+ ^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/response.py", line 92, in rendered_content
+ return template.render(context, self._request)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/backends/django.py", line 107, in render
+ return self.template.render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 171, in render
+ return self._render(context)
+ ^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 163, in _render
+ return self.nodelist.render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 1016, in render
+ return SafeString("".join([node.render_annotated(context) for node in self]))
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 977, in render_annotated
+ return self.render(context)
+ ^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/loader_tags.py", line 159, in render
+ return compiled_parent._render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 163, in _render
+ return self.nodelist.render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 1016, in render
+ return SafeString("".join([node.render_annotated(context) for node in self]))
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 977, in render_annotated
+ return self.render(context)
+ ^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/loader_tags.py", line 65, in render
+ result = block.nodelist.render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 1016, in render
+ return SafeString("".join([node.render_annotated(context) for node in self]))
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 977, in render_annotated
+ return self.render(context)
+ ^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/defaulttags.py", line 480, in render
+ url = reverse(view_name, args=args, kwargs=kwargs, current_app=current_app)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/urls/base.py", line 98, in reverse
+ resolved_url = resolver._reverse_with_prefix(view, prefix, *args, **kwargs)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/urls/resolvers.py", line 831, in _reverse_with_prefix
+ raise NoReverseMatch(msg)
+django.urls.exceptions.NoReverseMatch: Reverse for 'bill_details_api' with arguments '(0,)' not found. 1 pattern(s) tried: ['en/billing/bills/(?P[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})/\\Z']
+ERROR 2025-09-07 14:10:56,881 basehttp 7139 6202322944 "GET /en/billing/claims/create/ HTTP/1.1" 500 198003
+WARNING 2025-09-07 14:10:56,895 log 7139 6202322944 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 14:10:56,895 basehttp 7139 6202322944 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-07 14:11:45,306 autoreload 7139 8747049152 /Users/marwanalwali/manus_project/hospital_management_system_v4/billing/views.py changed, reloading.
+INFO 2025-09-07 14:11:45,662 autoreload 8942 8747049152 Watching for file changes with StatReloader
+ERROR 2025-09-07 14:11:47,998 log 8942 6157873152 Internal Server Error: /en/billing/claims/create/
+Traceback (most recent call last):
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/core/handlers/exception.py", line 55, in inner
+ response = get_response(request)
+ ^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/core/handlers/base.py", line 220, in _get_response
+ response = response.render()
+ ^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/response.py", line 114, in render
+ self.content = self.rendered_content
+ ^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/response.py", line 92, in rendered_content
+ return template.render(context, self._request)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/backends/django.py", line 107, in render
+ return self.template.render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 171, in render
+ return self._render(context)
+ ^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 163, in _render
+ return self.nodelist.render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 1016, in render
+ return SafeString("".join([node.render_annotated(context) for node in self]))
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 977, in render_annotated
+ return self.render(context)
+ ^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/loader_tags.py", line 159, in render
+ return compiled_parent._render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 163, in _render
+ return self.nodelist.render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 1016, in render
+ return SafeString("".join([node.render_annotated(context) for node in self]))
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 977, in render_annotated
+ return self.render(context)
+ ^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/loader_tags.py", line 65, in render
+ result = block.nodelist.render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 1016, in render
+ return SafeString("".join([node.render_annotated(context) for node in self]))
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 977, in render_annotated
+ return self.render(context)
+ ^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/defaulttags.py", line 480, in render
+ url = reverse(view_name, args=args, kwargs=kwargs, current_app=current_app)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/urls/base.py", line 98, in reverse
+ resolved_url = resolver._reverse_with_prefix(view, prefix, *args, **kwargs)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/urls/resolvers.py", line 831, in _reverse_with_prefix
+ raise NoReverseMatch(msg)
+django.urls.exceptions.NoReverseMatch: Reverse for 'bill_details_api' with arguments '(0,)' not found. 1 pattern(s) tried: ['en/billing/bills/(?P[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})/\\Z']
+ERROR 2025-09-07 14:11:48,000 basehttp 8942 6157873152 "GET /en/billing/claims/create/ HTTP/1.1" 500 198003
+WARNING 2025-09-07 14:11:48,016 log 8942 6157873152 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 14:11:48,016 basehttp 8942 6157873152 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+ERROR 2025-09-07 14:13:51,092 log 8942 6157873152 Internal Server Error: /en/billing/claims/create/
+Traceback (most recent call last):
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/core/handlers/exception.py", line 55, in inner
+ response = get_response(request)
+ ^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/core/handlers/base.py", line 220, in _get_response
+ response = response.render()
+ ^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/response.py", line 114, in render
+ self.content = self.rendered_content
+ ^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/response.py", line 92, in rendered_content
+ return template.render(context, self._request)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/backends/django.py", line 107, in render
+ return self.template.render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 171, in render
+ return self._render(context)
+ ^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 163, in _render
+ return self.nodelist.render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 1016, in render
+ return SafeString("".join([node.render_annotated(context) for node in self]))
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 977, in render_annotated
+ return self.render(context)
+ ^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/loader_tags.py", line 159, in render
+ return compiled_parent._render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 163, in _render
+ return self.nodelist.render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 1016, in render
+ return SafeString("".join([node.render_annotated(context) for node in self]))
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 977, in render_annotated
+ return self.render(context)
+ ^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/loader_tags.py", line 65, in render
+ result = block.nodelist.render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 1016, in render
+ return SafeString("".join([node.render_annotated(context) for node in self]))
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 977, in render_annotated
+ return self.render(context)
+ ^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/defaulttags.py", line 480, in render
+ url = reverse(view_name, args=args, kwargs=kwargs, current_app=current_app)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/urls/base.py", line 98, in reverse
+ resolved_url = resolver._reverse_with_prefix(view, prefix, *args, **kwargs)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/urls/resolvers.py", line 831, in _reverse_with_prefix
+ raise NoReverseMatch(msg)
+django.urls.exceptions.NoReverseMatch: Reverse for 'bill_details_api' with arguments '(0,)' not found. 1 pattern(s) tried: ['en/billing/bills/(?P[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})/\\Z']
+ERROR 2025-09-07 14:13:51,093 basehttp 8942 6157873152 "GET /en/billing/claims/create/ HTTP/1.1" 500 198021
+WARNING 2025-09-07 14:13:51,107 log 8942 6157873152 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 14:13:51,107 basehttp 8942 6157873152 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-07 14:17:09,213 autoreload 8942 8747049152 /Users/marwanalwali/manus_project/hospital_management_system_v4/billing/views.py changed, reloading.
+INFO 2025-09-07 14:17:09,525 autoreload 11319 8747049152 Watching for file changes with StatReloader
+INFO 2025-09-07 14:17:35,604 autoreload 11319 8747049152 /Users/marwanalwali/manus_project/hospital_management_system_v4/billing/urls.py changed, reloading.
+INFO 2025-09-07 14:17:35,925 autoreload 11481 8747049152 Watching for file changes with StatReloader
+ERROR 2025-09-07 14:18:02,757 log 11481 6171029504 Internal Server Error: /en/billing/claims/create/
+Traceback (most recent call last):
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/core/handlers/exception.py", line 55, in inner
+ response = get_response(request)
+ ^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/core/handlers/base.py", line 220, in _get_response
+ response = response.render()
+ ^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/response.py", line 114, in render
+ self.content = self.rendered_content
+ ^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/response.py", line 92, in rendered_content
+ return template.render(context, self._request)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/backends/django.py", line 107, in render
+ return self.template.render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 171, in render
+ return self._render(context)
+ ^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 163, in _render
+ return self.nodelist.render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 1016, in render
+ return SafeString("".join([node.render_annotated(context) for node in self]))
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 977, in render_annotated
+ return self.render(context)
+ ^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/loader_tags.py", line 159, in render
+ return compiled_parent._render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 163, in _render
+ return self.nodelist.render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 1016, in render
+ return SafeString("".join([node.render_annotated(context) for node in self]))
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 977, in render_annotated
+ return self.render(context)
+ ^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/loader_tags.py", line 65, in render
+ result = block.nodelist.render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 1016, in render
+ return SafeString("".join([node.render_annotated(context) for node in self]))
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 977, in render_annotated
+ return self.render(context)
+ ^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/defaulttags.py", line 480, in render
+ url = reverse(view_name, args=args, kwargs=kwargs, current_app=current_app)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/urls/base.py", line 98, in reverse
+ resolved_url = resolver._reverse_with_prefix(view, prefix, *args, **kwargs)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/urls/resolvers.py", line 831, in _reverse_with_prefix
+ raise NoReverseMatch(msg)
+django.urls.exceptions.NoReverseMatch: Reverse for 'insurance_details_api' not found. 'insurance_details_api' is not a valid view function or pattern name.
+ERROR 2025-09-07 14:18:02,758 basehttp 11481 6171029504 "GET /en/billing/claims/create/ HTTP/1.1" 500 194751
+WARNING 2025-09-07 14:18:02,776 log 11481 6171029504 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 14:18:02,776 basehttp 11481 6171029504 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-07 14:21:36,134 autoreload 11481 8747049152 /Users/marwanalwali/manus_project/hospital_management_system_v4/billing/views.py changed, reloading.
+INFO 2025-09-07 14:21:36,450 autoreload 13311 8747049152 Watching for file changes with StatReloader
+INFO 2025-09-07 14:30:21,471 autoreload 13311 8747049152 /Users/marwanalwali/manus_project/hospital_management_system_v4/patients/views.py changed, reloading.
+INFO 2025-09-07 14:30:21,814 autoreload 17159 8747049152 Watching for file changes with StatReloader
+ERROR 2025-09-07 14:30:22,942 log 17159 6201470976 Internal Server Error: /en/billing/claims/create/
+Traceback (most recent call last):
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/core/handlers/exception.py", line 55, in inner
+ response = get_response(request)
+ ^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/core/handlers/base.py", line 220, in _get_response
+ response = response.render()
+ ^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/response.py", line 114, in render
+ self.content = self.rendered_content
+ ^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/response.py", line 92, in rendered_content
+ return template.render(context, self._request)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/backends/django.py", line 107, in render
+ return self.template.render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 171, in render
+ return self._render(context)
+ ^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 163, in _render
+ return self.nodelist.render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 1016, in render
+ return SafeString("".join([node.render_annotated(context) for node in self]))
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 977, in render_annotated
+ return self.render(context)
+ ^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/loader_tags.py", line 159, in render
+ return compiled_parent._render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 163, in _render
+ return self.nodelist.render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 1016, in render
+ return SafeString("".join([node.render_annotated(context) for node in self]))
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 977, in render_annotated
+ return self.render(context)
+ ^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/loader_tags.py", line 65, in render
+ result = block.nodelist.render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 1016, in render
+ return SafeString("".join([node.render_annotated(context) for node in self]))
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 977, in render_annotated
+ return self.render(context)
+ ^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/defaulttags.py", line 480, in render
+ url = reverse(view_name, args=args, kwargs=kwargs, current_app=current_app)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/urls/base.py", line 98, in reverse
+ resolved_url = resolver._reverse_with_prefix(view, prefix, *args, **kwargs)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/urls/resolvers.py", line 831, in _reverse_with_prefix
+ raise NoReverseMatch(msg)
+django.urls.exceptions.NoReverseMatch: Reverse for 'bill_line_items_api' not found. 'bill_line_items_api' is not a valid view function or pattern name.
+ERROR 2025-09-07 14:30:22,944 basehttp 17159 6201470976 "GET /en/billing/claims/create/ HTTP/1.1" 500 194905
+WARNING 2025-09-07 14:30:22,954 log 17159 6201470976 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 14:30:22,954 basehttp 17159 6201470976 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-07 14:32:17,361 autoreload 17159 8747049152 /Users/marwanalwali/manus_project/hospital_management_system_v4/billing/urls.py changed, reloading.
+INFO 2025-09-07 14:32:17,711 autoreload 18042 8747049152 Watching for file changes with StatReloader
+INFO 2025-09-07 14:33:39,885 autoreload 18042 8747049152 /Users/marwanalwali/manus_project/hospital_management_system_v4/billing/views.py changed, reloading.
+INFO 2025-09-07 14:33:40,189 autoreload 18669 8747049152 Watching for file changes with StatReloader
+ERROR 2025-09-07 14:33:48,303 log 18669 6198521856 Internal Server Error: /en/billing/claims/create/
+Traceback (most recent call last):
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/core/handlers/exception.py", line 55, in inner
+ response = get_response(request)
+ ^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/core/handlers/base.py", line 220, in _get_response
+ response = response.render()
+ ^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/response.py", line 114, in render
+ self.content = self.rendered_content
+ ^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/response.py", line 92, in rendered_content
+ return template.render(context, self._request)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/backends/django.py", line 107, in render
+ return self.template.render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 171, in render
+ return self._render(context)
+ ^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 163, in _render
+ return self.nodelist.render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 1016, in render
+ return SafeString("".join([node.render_annotated(context) for node in self]))
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 977, in render_annotated
+ return self.render(context)
+ ^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/loader_tags.py", line 159, in render
+ return compiled_parent._render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 163, in _render
+ return self.nodelist.render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 1016, in render
+ return SafeString("".join([node.render_annotated(context) for node in self]))
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 977, in render_annotated
+ return self.render(context)
+ ^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/loader_tags.py", line 65, in render
+ result = block.nodelist.render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 1016, in render
+ return SafeString("".join([node.render_annotated(context) for node in self]))
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 977, in render_annotated
+ return self.render(context)
+ ^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/defaulttags.py", line 480, in render
+ url = reverse(view_name, args=args, kwargs=kwargs, current_app=current_app)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/urls/base.py", line 98, in reverse
+ resolved_url = resolver._reverse_with_prefix(view, prefix, *args, **kwargs)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/urls/resolvers.py", line 831, in _reverse_with_prefix
+ raise NoReverseMatch(msg)
+django.urls.exceptions.NoReverseMatch: Reverse for 'bill_line_items_api' with no arguments not found. 1 pattern(s) tried: ['en/billing/bills/(?P[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})/line\\-items\\Z']
+ERROR 2025-09-07 14:33:48,304 basehttp 18669 6198521856 "GET /en/billing/claims/create/ HTTP/1.1" 500 197447
+WARNING 2025-09-07 14:33:48,321 log 18669 6198521856 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 14:33:48,321 basehttp 18669 6198521856 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+ERROR 2025-09-07 14:35:02,948 log 18669 6198521856 Internal Server Error: /en/billing/claims/create/
+Traceback (most recent call last):
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/core/handlers/exception.py", line 55, in inner
+ response = get_response(request)
+ ^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/core/handlers/base.py", line 220, in _get_response
+ response = response.render()
+ ^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/response.py", line 114, in render
+ self.content = self.rendered_content
+ ^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/response.py", line 92, in rendered_content
+ return template.render(context, self._request)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/backends/django.py", line 107, in render
+ return self.template.render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 171, in render
+ return self._render(context)
+ ^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 163, in _render
+ return self.nodelist.render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 1016, in render
+ return SafeString("".join([node.render_annotated(context) for node in self]))
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 977, in render_annotated
+ return self.render(context)
+ ^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/loader_tags.py", line 159, in render
+ return compiled_parent._render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 163, in _render
+ return self.nodelist.render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 1016, in render
+ return SafeString("".join([node.render_annotated(context) for node in self]))
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 977, in render_annotated
+ return self.render(context)
+ ^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/loader_tags.py", line 65, in render
+ result = block.nodelist.render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 1016, in render
+ return SafeString("".join([node.render_annotated(context) for node in self]))
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 977, in render_annotated
+ return self.render(context)
+ ^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/defaulttags.py", line 480, in render
+ url = reverse(view_name, args=args, kwargs=kwargs, current_app=current_app)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/urls/base.py", line 98, in reverse
+ resolved_url = resolver._reverse_with_prefix(view, prefix, *args, **kwargs)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/urls/resolvers.py", line 831, in _reverse_with_prefix
+ raise NoReverseMatch(msg)
+django.urls.exceptions.NoReverseMatch: Reverse for 'claim_preview' not found. 'claim_preview' is not a valid view function or pattern name.
+ERROR 2025-09-07 14:35:02,949 basehttp 18669 6198521856 "GET /en/billing/claims/create/ HTTP/1.1" 500 194951
+WARNING 2025-09-07 14:35:02,965 log 18669 6198521856 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 14:35:02,965 basehttp 18669 6198521856 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-07 14:35:25,061 basehttp 18669 6198521856 "GET /en/billing/claims/create/ HTTP/1.1" 200 66340
+WARNING 2025-09-07 14:35:25,077 log 18669 6198521856 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 14:35:25,077 basehttp 18669 6198521856 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-07 14:35:25,140 basehttp 18669 6198521856 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 14:36:20,079 basehttp 18669 6198521856 "GET /en/billing/bills/49ecf1c4-8024-4107-ad14-0d46cf66fe79/ HTTP/1.1" 200 38565
+INFO 2025-09-07 14:36:25,152 basehttp 18669 6198521856 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+WARNING 2025-09-07 14:37:08,113 log 18669 6198521856 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 14:37:08,113 basehttp 18669 6198521856 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-07 14:37:30,410 basehttp 18669 6198521856 "GET /en/billing/claims/ HTTP/1.1" 200 147205
+WARNING 2025-09-07 14:37:30,426 log 18669 6198521856 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 14:37:30,426 basehttp 18669 6198521856 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-07 14:37:30,474 basehttp 18669 6198521856 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 14:37:39,286 basehttp 18669 6198521856 "GET /en/billing/claims/ HTTP/1.1" 200 147205
+WARNING 2025-09-07 14:37:39,304 log 18669 6198521856 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 14:37:39,305 basehttp 18669 6198521856 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-07 14:37:39,357 basehttp 18669 6198521856 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+ERROR 2025-09-07 14:37:40,782 log 18669 6198521856 Internal Server Error: /en/billing/claims/5237a09c-9179-4f06-a247-65ce91213492/
+Traceback (most recent call last):
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/core/handlers/exception.py", line 55, in inner
+ response = get_response(request)
+ ^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/core/handlers/base.py", line 220, in _get_response
+ response = response.render()
+ ^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/response.py", line 114, in render
+ self.content = self.rendered_content
+ ^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/response.py", line 92, in rendered_content
+ return template.render(context, self._request)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/backends/django.py", line 107, in render
+ return self.template.render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 171, in render
+ return self._render(context)
+ ^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 163, in _render
+ return self.nodelist.render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 1016, in render
+ return SafeString("".join([node.render_annotated(context) for node in self]))
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 977, in render_annotated
+ return self.render(context)
+ ^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/loader_tags.py", line 159, in render
+ return compiled_parent._render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 163, in _render
+ return self.nodelist.render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 1016, in render
+ return SafeString("".join([node.render_annotated(context) for node in self]))
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 977, in render_annotated
+ return self.render(context)
+ ^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/loader_tags.py", line 65, in render
+ result = block.nodelist.render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 1016, in render
+ return SafeString("".join([node.render_annotated(context) for node in self]))
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 977, in render_annotated
+ return self.render(context)
+ ^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/defaulttags.py", line 327, in render
+ return nodelist.render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 1016, in render
+ return SafeString("".join([node.render_annotated(context) for node in self]))
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 977, in render_annotated
+ return self.render(context)
+ ^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/defaulttags.py", line 480, in render
+ url = reverse(view_name, args=args, kwargs=kwargs, current_app=current_app)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/urls/base.py", line 98, in reverse
+ resolved_url = resolver._reverse_with_prefix(view, prefix, *args, **kwargs)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/urls/resolvers.py", line 831, in _reverse_with_prefix
+ raise NoReverseMatch(msg)
+django.urls.exceptions.NoReverseMatch: Reverse for 'claim_appeal' not found. 'claim_appeal' is not a valid view function or pattern name.
+ERROR 2025-09-07 14:37:40,784 basehttp 18669 6198521856 "GET /en/billing/claims/5237a09c-9179-4f06-a247-65ce91213492/ HTTP/1.1" 500 191204
+WARNING 2025-09-07 14:37:40,802 log 18669 6198521856 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 14:37:40,802 basehttp 18669 6198521856 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-07 14:41:07,375 basehttp 18669 6198521856 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+WARNING 2025-09-07 14:41:07,377 log 18669 6215348224 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 14:41:07,377 basehttp 18669 6215348224 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+WARNING 2025-09-07 14:41:07,390 log 18669 6215348224 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 14:41:07,391 basehttp 18669 6215348224 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-07 14:41:11,966 basehttp 18669 6215348224 "GET /en/hr HTTP/1.1" 301 0
+INFO 2025-09-07 14:41:12,005 basehttp 18669 6198521856 "GET /en/hr/ HTTP/1.1" 200 42394
+WARNING 2025-09-07 14:41:12,022 log 18669 6198521856 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 14:41:12,022 basehttp 18669 6198521856 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-07 14:41:12,038 basehttp 18669 6198521856 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+ERROR 2025-09-07 14:41:32,945 log 18669 6198521856 Internal Server Error: /en/hr/departments/
+Traceback (most recent call last):
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/core/handlers/exception.py", line 55, in inner
+ response = get_response(request)
+ ^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/core/handlers/base.py", line 220, in _get_response
+ response = response.render()
+ ^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/response.py", line 114, in render
+ self.content = self.rendered_content
+ ^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/response.py", line 90, in rendered_content
+ template = self.resolve_template(self.template_name)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/response.py", line 72, in resolve_template
+ return select_template(template, using=self.using)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/loader.py", line 47, in select_template
+ raise TemplateDoesNotExist(", ".join(template_name_list), chain=chain)
+django.template.exceptions.TemplateDoesNotExist: hr/department_list.html, hr/department_list.html
+ERROR 2025-09-07 14:41:32,946 basehttp 18669 6198521856 "GET /en/hr/departments/ HTTP/1.1" 500 86314
+WARNING 2025-09-07 14:41:32,965 log 18669 6198521856 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 14:41:32,966 basehttp 18669 6198521856 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-07 14:44:30,725 autoreload 18669 8747049152 /Users/marwanalwali/manus_project/hospital_management_system_v4/hr/views.py changed, reloading.
+INFO 2025-09-07 14:44:31,100 autoreload 23535 8747049152 Watching for file changes with StatReloader
+INFO 2025-09-07 14:48:28,470 basehttp 23535 6201683968 "GET /en/hr/departments/ HTTP/1.1" 200 125426
+INFO 2025-09-07 14:48:28,486 basehttp 23535 6218510336 "GET /static/plugins/datatables.net-buttons-bs5/css/buttons.bootstrap5.min.css HTTP/1.1" 200 8136
+WARNING 2025-09-07 14:48:28,488 log 23535 6201683968 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 14:48:28,488 basehttp 23535 6201683968 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-07 14:48:28,490 basehttp 23535 6218510336 "GET /static/plugins/datatables.net-buttons-bs5/js/buttons.bootstrap5.min.js HTTP/1.1" 200 1627
+INFO 2025-09-07 14:48:28,492 basehttp 23535 6201683968 "GET /static/plugins/datatables.net-buttons/js/dataTables.buttons.min.js HTTP/1.1" 200 27926
+INFO 2025-09-07 14:48:28,492 basehttp 23535 6252163072 "GET /static/plugins/datatables.net-buttons/js/buttons.print.min.js HTTP/1.1" 200 3073
+INFO 2025-09-07 14:48:28,492 basehttp 23535 6235336704 "GET /static/plugins/datatables.net-buttons/js/buttons.html5.min.js HTTP/1.1" 200 26043
+INFO 2025-09-07 14:48:28,498 basehttp 23535 6268989440 "GET /static/plugins/jszip/dist/jszip.min.js HTTP/1.1" 200 97630
+INFO 2025-09-07 14:48:28,504 basehttp 23535 6218510336 "GET /static/plugins/pdfmake/build/vfs_fonts.js HTTP/1.1" 200 828866
+INFO 2025-09-07 14:48:28,505 basehttp 23535 6285815808 "GET /static/plugins/pdfmake/build/pdfmake.min.js HTTP/1.1" 200 1400771
+INFO 2025-09-07 14:48:28,604 basehttp 23535 6218510336 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 14:48:28,606 basehttp 23535 6285815808 "GET /static/plugins/pdfmake/build/pdfmake.min.js.map HTTP/1.1" 200 4214503
+INFO 2025-09-07 14:48:47,353 basehttp 23535 6285815808 "GET /en/hr/departments/create/ HTTP/1.1" 200 41288
+WARNING 2025-09-07 14:48:47,364 basehttp 23535 6285815808 "GET /static/plugins/select2-bootstrap5-theme/select2-bootstrap5.min.css HTTP/1.1" 404 2104
+WARNING 2025-09-07 14:48:47,373 log 23535 6218510336 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 14:48:47,373 basehttp 23535 6218510336 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-07 14:48:47,444 basehttp 23535 6218510336 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 14:49:02,684 basehttp 23535 6218510336 "GET /en/hr/departments/ HTTP/1.1" 200 125426
+WARNING 2025-09-07 14:49:02,703 log 23535 6218510336 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 14:49:02,703 basehttp 23535 6218510336 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-07 14:49:02,798 basehttp 23535 6218510336 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 14:49:04,753 basehttp 23535 6218510336 "GET /en/hr/departments/12/ HTTP/1.1" 200 35129
+WARNING 2025-09-07 14:49:04,775 basehttp 23535 6218510336 "GET /static/plugins/chart.js/dist/Chart.min.css HTTP/1.1" 404 2032
+WARNING 2025-09-07 14:49:04,775 basehttp 23535 6268989440 "GET /static/plugins/datatables.net/js/jquery.dataTables.min.js HTTP/1.1" 404 2077
+WARNING 2025-09-07 14:49:04,775 basehttp 23535 6235336704 "GET /static/plugins/chart.js/dist/Chart.min.js HTTP/1.1" 404 2029
+WARNING 2025-09-07 14:49:04,781 log 23535 6252163072 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 14:49:04,781 basehttp 23535 6252163072 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-07 14:49:04,825 basehttp 23535 6252163072 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 14:49:56,931 basehttp 23535 6252163072 "GET /en/hr/departments/12/update/ HTTP/1.1" 200 41458
+WARNING 2025-09-07 14:49:56,950 basehttp 23535 6201683968 "GET /static/plugins/select2-bootstrap5-theme/select2-bootstrap5.min.css HTTP/1.1" 404 2104
+WARNING 2025-09-07 14:49:56,954 log 23535 6252163072 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 14:49:56,954 basehttp 23535 6252163072 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-07 14:49:57,005 basehttp 23535 6252163072 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+WARNING 2025-09-07 14:50:03,717 basehttp 23535 6201683968 "GET /static/plugins/chart.js/dist/Chart.min.css HTTP/1.1" 404 2032
+WARNING 2025-09-07 14:50:03,721 log 23535 6252163072 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 14:50:03,721 basehttp 23535 6252163072 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+WARNING 2025-09-07 14:50:03,732 log 23535 6252163072 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 14:50:03,732 basehttp 23535 6252163072 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-07 14:50:04,847 basehttp 23535 6252163072 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+WARNING 2025-09-07 14:50:10,725 log 23535 6201683968 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+INFO 2025-09-07 14:50:10,725 basehttp 23535 6252163072 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+WARNING 2025-09-07 14:50:10,725 basehttp 23535 6201683968 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+WARNING 2025-09-07 14:50:10,741 log 23535 6252163072 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 14:50:10,741 basehttp 23535 6252163072 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-07 14:50:13,335 basehttp 23535 6252163072 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+WARNING 2025-09-07 14:50:13,338 log 23535 6201683968 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 14:50:13,340 basehttp 23535 6252163072 "GET /static/plugins/select2-bootstrap5-theme/select2-bootstrap5.min.css HTTP/1.1" 404 2104
+WARNING 2025-09-07 14:50:13,340 basehttp 23535 6201683968 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+WARNING 2025-09-07 14:50:13,352 log 23535 6201683968 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 14:50:13,352 basehttp 23535 6201683968 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+WARNING 2025-09-07 14:50:14,669 log 23535 6218510336 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 14:50:14,669 basehttp 23535 6218510336 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-07 14:50:14,671 basehttp 23535 6201683968 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+WARNING 2025-09-07 14:50:14,684 log 23535 6201683968 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 14:50:14,684 basehttp 23535 6201683968 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+WARNING 2025-09-07 14:50:17,041 log 23535 6235336704 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 14:50:17,042 basehttp 23535 6235336704 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-07 14:50:17,044 basehttp 23535 6201683968 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+WARNING 2025-09-07 14:50:17,051 log 23535 6201683968 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 14:50:17,051 basehttp 23535 6201683968 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-07 14:50:17,057 basehttp 23535 6218510336 "GET /en/hr/htmx/stats/ HTTP/1.1" 200 4459
+INFO 2025-09-07 14:50:18,074 basehttp 23535 6218510336 "GET /en/hr/ HTTP/1.1" 200 42394
+WARNING 2025-09-07 14:50:18,091 log 23535 6218510336 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 14:50:18,091 basehttp 23535 6218510336 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-07 14:50:18,143 basehttp 23535 6218510336 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 14:50:19,416 basehttp 23535 6218510336 "GET /en/hr/employees/ HTTP/1.1" 200 130495
+WARNING 2025-09-07 14:50:19,439 log 23535 6218510336 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 14:50:19,439 basehttp 23535 6218510336 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-07 14:50:19,483 basehttp 23535 6218510336 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 14:50:32,151 basehttp 23535 6218510336 "GET /en/hr/employees/56/ HTTP/1.1" 200 34482
+WARNING 2025-09-07 14:50:32,175 log 23535 6218510336 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 14:50:32,175 basehttp 23535 6218510336 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-07 14:50:32,215 basehttp 23535 6218510336 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+WARNING 2025-09-07 14:50:39,307 log 23535 6218510336 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 14:50:39,307 basehttp 23535 6218510336 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+WARNING 2025-09-07 14:50:39,323 log 23535 6218510336 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 14:50:39,323 basehttp 23535 6218510336 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+WARNING 2025-09-07 14:50:40,377 log 23535 6218510336 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 14:50:40,377 basehttp 23535 6218510336 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+WARNING 2025-09-07 14:50:40,389 log 23535 6218510336 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 14:50:40,389 basehttp 23535 6218510336 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+WARNING 2025-09-07 14:50:41,063 log 23535 6218510336 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 14:50:41,063 basehttp 23535 6218510336 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+WARNING 2025-09-07 14:50:41,949 log 23535 6218510336 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 14:50:41,949 basehttp 23535 6218510336 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+WARNING 2025-09-07 14:50:42,797 log 23535 6218510336 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 14:50:42,797 basehttp 23535 6218510336 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-07 14:50:55,783 basehttp 23535 6218510336 "GET /en/hr/ HTTP/1.1" 200 42394
+WARNING 2025-09-07 14:50:55,805 log 23535 6218510336 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 14:50:55,805 basehttp 23535 6218510336 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-07 14:50:55,822 basehttp 23535 6218510336 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 14:50:59,805 basehttp 23535 6218510336 "GET /en/hr/schedules/ HTTP/1.1" 200 121762
+WARNING 2025-09-07 14:50:59,829 basehttp 23535 6201683968 "GET /static/plugins/fullcalendar/main.min.css HTTP/1.1" 404 2026
+WARNING 2025-09-07 14:50:59,831 basehttp 23535 6252163072 "GET /static/plugins/fullcalendar/main.min.js HTTP/1.1" 404 2023
+WARNING 2025-09-07 14:50:59,831 basehttp 23535 6235336704 "GET /static/plugins/datatables.net/js/jquery.dataTables.min.js HTTP/1.1" 404 2077
+WARNING 2025-09-07 14:50:59,840 log 23535 6218510336 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 14:50:59,840 basehttp 23535 6218510336 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-07 14:50:59,883 basehttp 23535 6218510336 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 14:51:59,904 basehttp 23535 6218510336 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 14:52:59,891 basehttp 23535 6218510336 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 14:53:19,615 basehttp 23535 6218510336 "GET /en/hr/schedules/ HTTP/1.1" 200 121575
+WARNING 2025-09-07 14:53:19,625 basehttp 23535 6218510336 "GET /static/plugins/datatables.net/js/jquery.dataTables.min.js HTTP/1.1" 404 2077
+WARNING 2025-09-07 14:53:19,625 basehttp 23535 6201683968 "GET /static/plugins/fullcalendar/main.min.js HTTP/1.1" 404 2023
+WARNING 2025-09-07 14:53:19,631 log 23535 6201683968 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 14:53:19,631 basehttp 23535 6201683968 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-07 14:53:19,688 basehttp 23535 6201683968 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 14:53:21,928 basehttp 23535 6201683968 "GET /en/hr/schedules/ HTTP/1.1" 200 121575
+WARNING 2025-09-07 14:53:21,939 basehttp 23535 6201683968 "GET /static/plugins/datatables.net/js/jquery.dataTables.min.js HTTP/1.1" 404 2077
+WARNING 2025-09-07 14:53:21,939 basehttp 23535 6218510336 "GET /static/plugins/fullcalendar/main.min.js HTTP/1.1" 404 2023
+WARNING 2025-09-07 14:53:21,945 log 23535 6235336704 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 14:53:21,945 basehttp 23535 6235336704 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-07 14:53:21,997 basehttp 23535 6235336704 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 14:53:31,828 basehttp 23535 6235336704 "GET /en/hr/schedules/?page=2 HTTP/1.1" 200 122790
+WARNING 2025-09-07 14:53:31,847 basehttp 23535 6235336704 "GET /static/plugins/datatables.net/js/jquery.dataTables.min.js HTTP/1.1" 404 2077
+WARNING 2025-09-07 14:53:31,848 basehttp 23535 6201683968 "GET /static/plugins/fullcalendar/main.min.js HTTP/1.1" 404 2023
+WARNING 2025-09-07 14:53:31,854 log 23535 6218510336 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 14:53:31,854 basehttp 23535 6218510336 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-07 14:53:31,896 basehttp 23535 6218510336 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 14:54:32,350 basehttp 23535 6218510336 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 14:55:33,351 basehttp 23535 6218510336 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 14:56:34,352 basehttp 23535 6218510336 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 14:57:35,360 basehttp 23535 6218510336 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 14:58:07,336 basehttp 23535 6218510336 "GET /en/hr/schedules/?page=2 HTTP/1.1" 200 123284
+INFO 2025-09-07 14:58:07,344 basehttp 23535 6218510336 "GET /static/plugins/moment/min/moment.min.js HTTP/1.1" 200 58890
+INFO 2025-09-07 14:58:07,356 basehttp 23535 6285815808 "GET /static/plugins/%40fullcalendar/bootstrap/index.global.js HTTP/1.1" 200 2075
+INFO 2025-09-07 14:58:07,356 basehttp 23535 6235336704 "GET /static/plugins/%40fullcalendar/timegrid/index.global.js HTTP/1.1" 200 68582
+INFO 2025-09-07 14:58:07,357 basehttp 23535 6268989440 "GET /static/plugins/%40fullcalendar/list/index.global.js HTTP/1.1" 200 18635
+INFO 2025-09-07 14:58:07,357 basehttp 23535 6201683968 "GET /static/plugins/%40fullcalendar/daygrid/index.global.js HTTP/1.1" 200 58461
+INFO 2025-09-07 14:58:07,358 basehttp 23535 6252163072 "GET /static/plugins/%40fullcalendar/interaction/index.global.js HTTP/1.1" 200 99452
+INFO 2025-09-07 14:58:07,362 basehttp 23535 6218510336 "GET /static/plugins/%40fullcalendar/core/index.global.js HTTP/1.1" 200 444856
+WARNING 2025-09-07 14:58:07,366 log 23535 6252163072 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 14:58:07,366 basehttp 23535 6252163072 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-07 14:58:07,428 basehttp 23535 6252163072 "GET /static/plugins/moment/min/moment.min.js.map HTTP/1.1" 200 98730
+INFO 2025-09-07 14:58:07,467 basehttp 23535 6252163072 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 14:58:10,732 basehttp 23535 6252163072 "GET /en/hr/schedules/?page=2 HTTP/1.1" 200 123284
+INFO 2025-09-07 14:58:10,740 basehttp 23535 6201683968 "GET /static/css/custom.css HTTP/1.1" 200 2063
+INFO 2025-09-07 14:58:10,742 basehttp 23535 6235336704 "GET /static/plugins/datatables.net-bs5/css/dataTables.bootstrap5.min.css HTTP/1.1" 200 15096
+INFO 2025-09-07 14:58:10,743 basehttp 23535 6268989440 "GET /static/plugins/datatables.net-responsive-bs5/css/responsive.bootstrap5.min.css HTTP/1.1" 200 6044
+WARNING 2025-09-07 14:58:10,748 log 23535 6201683968 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+INFO 2025-09-07 14:58:10,748 basehttp 23535 6285815808 "GET /static/js/htmx.min.js HTTP/1.1" 200 50917
+WARNING 2025-09-07 14:58:10,749 basehttp 23535 6201683968 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-07 14:58:10,749 basehttp 23535 6235336704 "GET /static/img/user/user-4.jpg HTTP/1.1" 200 5916
+INFO 2025-09-07 14:58:10,753 basehttp 23535 6201683968 "GET /static/plugins/moment/min/moment.min.js HTTP/1.1" 200 58890
+INFO 2025-09-07 14:58:10,755 basehttp 23535 6252163072 "GET /static/css/vendor.min.css HTTP/1.1" 200 177466
+INFO 2025-09-07 14:58:10,756 basehttp 23535 6201683968 "GET /static/plugins/datatables.net-bs5/js/dataTables.bootstrap5.min.js HTTP/1.1" 200 1470
+INFO 2025-09-07 14:58:10,759 basehttp 23535 6285815808 "GET /static/js/app.min.js HTTP/1.1" 200 110394
+INFO 2025-09-07 14:58:10,760 basehttp 23535 6235336704 "GET /static/plugins/datatables.net/js/dataTables.min.js HTTP/1.1" 200 95735
+INFO 2025-09-07 14:58:10,760 basehttp 23535 6201683968 "GET /static/plugins/datatables.net-responsive-bs5/js/responsive.bootstrap5.min.js HTTP/1.1" 200 1796
+INFO 2025-09-07 14:58:10,762 basehttp 23535 6252163072 "GET /static/plugins/datatables.net-responsive/js/dataTables.responsive.min.js HTTP/1.1" 200 16086
+INFO 2025-09-07 14:58:10,765 basehttp 23535 6235336704 "GET /static/plugins/%40fullcalendar/timegrid/index.global.js HTTP/1.1" 200 68582
+INFO 2025-09-07 14:58:10,766 basehttp 23535 6201683968 "GET /static/plugins/%40fullcalendar/daygrid/index.global.js HTTP/1.1" 200 58461
+INFO 2025-09-07 14:58:10,768 basehttp 23535 6252163072 "GET /static/plugins/%40fullcalendar/interaction/index.global.js HTTP/1.1" 200 99452
+INFO 2025-09-07 14:58:10,769 basehttp 23535 6235336704 "GET /static/plugins/%40fullcalendar/bootstrap/index.global.js HTTP/1.1" 200 2075
+INFO 2025-09-07 14:58:10,769 basehttp 23535 6201683968 "GET /static/plugins/%40fullcalendar/list/index.global.js HTTP/1.1" 200 18635
+INFO 2025-09-07 14:58:10,770 basehttp 23535 6218510336 "GET /static/css/default/app.min.css HTTP/1.1" 200 893480
+INFO 2025-09-07 14:58:10,770 basehttp 23535 6285815808 "GET /static/plugins/%40fullcalendar/core/index.global.js HTTP/1.1" 200 444856
+INFO 2025-09-07 14:58:10,770 basehttp 23535 6268989440 "GET /static/js/vendor.min.js HTTP/1.1" 200 1091361
+INFO 2025-09-07 14:58:11,753 basehttp 23535 6285815808 "GET /static/css/default/app.min.css.map HTTP/1.1" 200 1957526
+INFO 2025-09-07 14:58:11,774 basehttp 23535 6268989440 "GET /static/img/theme/transparent.jpg HTTP/1.1" 200 32747
+INFO 2025-09-07 14:58:11,774 basehttp 23535 6285815808 "GET /static/img/theme/default.jpg HTTP/1.1" 200 26964
+INFO 2025-09-07 14:58:11,774 basehttp 23535 6252163072 "GET /static/img/theme/facebook.jpg HTTP/1.1" 200 27881
+INFO 2025-09-07 14:58:11,775 basehttp 23535 6218510336 "GET /static/img/theme/material.jpg HTTP/1.1" 200 28774
+INFO 2025-09-07 14:58:11,776 basehttp 23535 6201683968 "GET /static/img/theme/apple.jpg HTTP/1.1" 200 28822
+INFO 2025-09-07 14:58:11,779 basehttp 23535 6285815808 "GET /static/img/version/ajax.jpg HTTP/1.1" 200 20223
+INFO 2025-09-07 14:58:11,779 basehttp 23535 6235336704 "GET /static/img/theme/google.jpg HTTP/1.1" 200 86013
+INFO 2025-09-07 14:58:11,780 basehttp 23535 6218510336 "GET /static/img/version/angular1x.jpg HTTP/1.1" 200 22869
+INFO 2025-09-07 14:58:11,780 basehttp 23535 6252163072 "GET /static/img/version/html.jpg HTTP/1.1" 200 17325
+INFO 2025-09-07 14:58:11,780 basehttp 23535 6201683968 "GET /static/img/version/angular10x.jpg HTTP/1.1" 200 24580
+INFO 2025-09-07 14:58:11,782 basehttp 23535 6235336704 "GET /static/img/version/svelte.jpg HTTP/1.1" 200 25060
+INFO 2025-09-07 14:58:11,782 basehttp 23535 6285815808 "GET /static/img/version/laravel.jpg HTTP/1.1" 200 26040
+INFO 2025-09-07 14:58:11,782 basehttp 23535 6252163072 "GET /static/img/version/django.jpg HTTP/1.1" 200 20935
+INFO 2025-09-07 14:58:11,783 basehttp 23535 6201683968 "GET /static/img/version/reactjs.jpg HTTP/1.1" 200 26850
+INFO 2025-09-07 14:58:11,783 basehttp 23535 6218510336 "GET /static/img/version/vuejs.jpg HTTP/1.1" 200 22518
+INFO 2025-09-07 14:58:11,785 basehttp 23535 6235336704 "GET /static/img/version/dotnet.jpg HTTP/1.1" 200 24791
+INFO 2025-09-07 14:58:11,785 basehttp 23535 6268989440 "GET /static/webfonts/fa-solid-900.woff2 HTTP/1.1" 200 158220
+INFO 2025-09-07 14:58:11,786 basehttp 23535 6252163072 "GET /static/img/version/nextjs.jpg HTTP/1.1" 200 20152
+INFO 2025-09-07 14:58:11,787 basehttp 23535 6235336704 "GET /static/img/theme/forum.jpg HTTP/1.1" 200 28744
+INFO 2025-09-07 14:58:11,787 basehttp 23535 6201683968 "GET /static/img/theme/blog.jpg HTTP/1.1" 200 32334
+INFO 2025-09-07 14:58:11,787 basehttp 23535 6218510336 "GET /static/img/theme/e-commerce.jpg HTTP/1.1" 200 37734
+INFO 2025-09-07 14:58:11,788 basehttp 23535 6268989440 "GET /static/img/theme/corporate.jpg HTTP/1.1" 200 38911
+INFO 2025-09-07 14:58:11,788 basehttp 23535 6285815808 "GET /static/img/theme/one-page-parallax.jpg HTTP/1.1" 200 22474
+INFO 2025-09-07 14:58:11,790 basehttp 23535 6285815808 "GET /static/plugins/moment/min/moment.min.js.map HTTP/1.1" 200 98730
+INFO 2025-09-07 14:58:11,812 basehttp 23535 6285815808 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+WARNING 2025-09-07 14:58:11,937 log 23535 6285815808 Not Found: /favicon.ico
+WARNING 2025-09-07 14:58:11,943 basehttp 23535 6285815808 "GET /favicon.ico HTTP/1.1" 404 2557
+INFO 2025-09-07 14:59:11,824 basehttp 23535 6285815808 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 15:00:12,344 basehttp 23535 6285815808 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+ERROR 2025-09-07 15:01:02,531 log 23535 6285815808 Internal Server Error: /en/hr/schedules/21/
+Traceback (most recent call last):
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/core/handlers/exception.py", line 55, in inner
+ response = get_response(request)
+ ^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/core/handlers/base.py", line 220, in _get_response
+ response = response.render()
+ ^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/response.py", line 114, in render
+ self.content = self.rendered_content
+ ^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/response.py", line 92, in rendered_content
+ return template.render(context, self._request)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/backends/django.py", line 107, in render
+ return self.template.render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 171, in render
+ return self._render(context)
+ ^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 163, in _render
+ return self.nodelist.render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 1016, in render
+ return SafeString("".join([node.render_annotated(context) for node in self]))
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 977, in render_annotated
+ return self.render(context)
+ ^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/loader_tags.py", line 159, in render
+ return compiled_parent._render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 163, in _render
+ return self.nodelist.render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 1016, in render
+ return SafeString("".join([node.render_annotated(context) for node in self]))
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 977, in render_annotated
+ return self.render(context)
+ ^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/loader_tags.py", line 65, in render
+ result = block.nodelist.render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 1016, in render
+ return SafeString("".join([node.render_annotated(context) for node in self]))
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 977, in render_annotated
+ return self.render(context)
+ ^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/defaulttags.py", line 243, in render
+ nodelist.append(node.render_annotated(context))
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 977, in render_annotated
+ return self.render(context)
+ ^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/defaulttags.py", line 480, in render
+ url = reverse(view_name, args=args, kwargs=kwargs, current_app=current_app)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/urls/base.py", line 98, in reverse
+ resolved_url = resolver._reverse_with_prefix(view, prefix, *args, **kwargs)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/urls/resolvers.py", line 831, in _reverse_with_prefix
+ raise NoReverseMatch(msg)
+django.urls.exceptions.NoReverseMatch: Reverse for 'schedule_assignment_delete' not found. 'schedule_assignment_delete' is not a valid view function or pattern name.
+ERROR 2025-09-07 15:01:02,532 basehttp 23535 6285815808 "GET /en/hr/schedules/21/ HTTP/1.1" 500 224610
+WARNING 2025-09-07 15:01:02,554 log 23535 6285815808 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 15:01:02,554 basehttp 23535 6285815808 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+ERROR 2025-09-07 15:02:26,622 log 23535 6285815808 Internal Server Error: /en/hr/schedules/21/
+Traceback (most recent call last):
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/core/handlers/exception.py", line 55, in inner
+ response = get_response(request)
+ ^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/core/handlers/base.py", line 220, in _get_response
+ response = response.render()
+ ^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/response.py", line 114, in render
+ self.content = self.rendered_content
+ ^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/response.py", line 92, in rendered_content
+ return template.render(context, self._request)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/backends/django.py", line 107, in render
+ return self.template.render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 171, in render
+ return self._render(context)
+ ^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 163, in _render
+ return self.nodelist.render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 1016, in render
+ return SafeString("".join([node.render_annotated(context) for node in self]))
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 977, in render_annotated
+ return self.render(context)
+ ^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/loader_tags.py", line 159, in render
+ return compiled_parent._render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 163, in _render
+ return self.nodelist.render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 1016, in render
+ return SafeString("".join([node.render_annotated(context) for node in self]))
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 977, in render_annotated
+ return self.render(context)
+ ^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/loader_tags.py", line 65, in render
+ result = block.nodelist.render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 1016, in render
+ return SafeString("".join([node.render_annotated(context) for node in self]))
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 977, in render_annotated
+ return self.render(context)
+ ^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/defaulttags.py", line 480, in render
+ url = reverse(view_name, args=args, kwargs=kwargs, current_app=current_app)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/urls/base.py", line 98, in reverse
+ resolved_url = resolver._reverse_with_prefix(view, prefix, *args, **kwargs)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/urls/resolvers.py", line 831, in _reverse_with_prefix
+ raise NoReverseMatch(msg)
+django.urls.exceptions.NoReverseMatch: Reverse for 'export_schedule' not found. 'export_schedule' is not a valid view function or pattern name.
+ERROR 2025-09-07 15:02:26,623 basehttp 23535 6285815808 "GET /en/hr/schedules/21/ HTTP/1.1" 500 204110
+WARNING 2025-09-07 15:02:26,639 log 23535 6285815808 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 15:02:26,640 basehttp 23535 6285815808 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-07 15:03:24,515 basehttp 23535 6285815808 "GET /en/hr/schedules/21/ HTTP/1.1" 200 173472
+WARNING 2025-09-07 15:03:24,526 basehttp 23535 6285815808 "GET /static/img/user/default-avatar.jpg HTTP/1.1" 404 2008
+INFO 2025-09-07 15:03:24,527 basehttp 23535 6201683968 "GET /static/plugins/chart.js/dist/chart.umd.js HTTP/1.1" 200 206279
+WARNING 2025-09-07 15:03:24,532 log 23535 6218510336 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 15:03:24,532 basehttp 23535 6218510336 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+WARNING 2025-09-07 15:03:24,566 basehttp 23535 6218510336 "GET /static/img/user/default-avatar.jpg HTTP/1.1" 404 2008
+INFO 2025-09-07 15:03:24,638 basehttp 23535 6201683968 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 15:03:24,643 basehttp 23535 6201683968 "GET /static/plugins/chart.js/dist/chart.umd.js.map HTTP/1.1" 200 958364
+WARNING 2025-09-07 15:03:24,656 basehttp 23535 6201683968 "GET /static/img/user/default-avatar.jpg HTTP/1.1" 404 2008
+INFO 2025-09-07 15:03:49,585 basehttp 23535 6201683968 "GET /en/hr/schedules/21/ HTTP/1.1" 200 173472
+INFO 2025-09-07 15:03:49,597 basehttp 23535 6252163072 "GET /static/css/custom.css HTTP/1.1" 200 2063
+INFO 2025-09-07 15:03:49,598 basehttp 23535 6285815808 "GET /static/plugins/datatables.net-responsive-bs5/css/responsive.bootstrap5.min.css HTTP/1.1" 200 6044
+INFO 2025-09-07 15:03:49,599 basehttp 23535 6268989440 "GET /static/plugins/datatables.net-bs5/css/dataTables.bootstrap5.min.css HTTP/1.1" 200 15096
+INFO 2025-09-07 15:03:49,601 basehttp 23535 6252163072 "GET /static/js/htmx.min.js HTTP/1.1" 200 50917
+WARNING 2025-09-07 15:03:49,602 log 23535 6201683968 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 15:03:49,602 basehttp 23535 6201683968 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-07 15:03:49,603 basehttp 23535 6218510336 "GET /static/css/vendor.min.css HTTP/1.1" 200 177466
+INFO 2025-09-07 15:03:49,604 basehttp 23535 6235336704 "GET /static/css/default/app.min.css HTTP/1.1" 200 893480
+WARNING 2025-09-07 15:03:49,685 basehttp 23535 6218510336 "GET /static/img/user/default-avatar.jpg HTTP/1.1" 404 2008
+INFO 2025-09-07 15:03:49,685 basehttp 23535 6235336704 "GET /static/img/user/user-4.jpg HTTP/1.1" 200 5916
+INFO 2025-09-07 15:03:49,687 basehttp 23535 6201683968 "GET /static/js/app.min.js HTTP/1.1" 200 110394
+INFO 2025-09-07 15:03:49,689 basehttp 23535 6201683968 "GET /static/plugins/datatables.net/js/dataTables.min.js HTTP/1.1" 200 95735
+INFO 2025-09-07 15:03:49,690 basehttp 23535 6235336704 "GET /static/js/vendor.min.js HTTP/1.1" 200 1091361
+INFO 2025-09-07 15:03:49,690 basehttp 23535 6201683968 "GET /static/plugins/datatables.net-bs5/js/dataTables.bootstrap5.min.js HTTP/1.1" 200 1470
+INFO 2025-09-07 15:03:49,691 basehttp 23535 6201683968 "GET /static/plugins/datatables.net-responsive/js/dataTables.responsive.min.js HTTP/1.1" 200 16086
+INFO 2025-09-07 15:03:49,692 basehttp 23535 6235336704 "GET /static/plugins/datatables.net-responsive-bs5/js/responsive.bootstrap5.min.js HTTP/1.1" 200 1796
+INFO 2025-09-07 15:03:49,693 basehttp 23535 6235336704 "GET /static/plugins/%40fullcalendar/daygrid/index.global.js HTTP/1.1" 200 58461
+INFO 2025-09-07 15:03:49,694 basehttp 23535 6201683968 "GET /static/plugins/%40fullcalendar/core/index.global.js HTTP/1.1" 200 444856
+INFO 2025-09-07 15:03:49,695 basehttp 23535 6235336704 "GET /static/plugins/%40fullcalendar/timegrid/index.global.js HTTP/1.1" 200 68582
+INFO 2025-09-07 15:03:49,695 basehttp 23535 6201683968 "GET /static/plugins/%40fullcalendar/interaction/index.global.js HTTP/1.1" 200 99452
+INFO 2025-09-07 15:03:49,696 basehttp 23535 6235336704 "GET /static/plugins/%40fullcalendar/list/index.global.js HTTP/1.1" 200 18635
+INFO 2025-09-07 15:03:49,696 basehttp 23535 6201683968 "GET /static/plugins/%40fullcalendar/bootstrap/index.global.js HTTP/1.1" 200 2075
+INFO 2025-09-07 15:03:49,697 basehttp 23535 6235336704 "GET /static/plugins/chart.js/dist/chart.umd.js HTTP/1.1" 200 206279
+WARNING 2025-09-07 15:03:50,486 basehttp 23535 6201683968 "GET /static/img/user/default-avatar.jpg HTTP/1.1" 404 2008
+INFO 2025-09-07 15:03:50,487 basehttp 23535 6235336704 "GET /static/css/default/app.min.css.map HTTP/1.1" 200 1957526
+INFO 2025-09-07 15:03:50,509 basehttp 23535 6252163072 "GET /static/img/theme/transparent.jpg HTTP/1.1" 200 32747
+INFO 2025-09-07 15:03:50,510 basehttp 23535 6235336704 "GET /static/img/theme/default.jpg HTTP/1.1" 200 26964
+INFO 2025-09-07 15:03:50,511 basehttp 23535 6201683968 "GET /static/img/theme/facebook.jpg HTTP/1.1" 200 27881
+INFO 2025-09-07 15:03:50,512 basehttp 23535 6268989440 "GET /static/img/theme/apple.jpg HTTP/1.1" 200 28822
+INFO 2025-09-07 15:03:50,512 basehttp 23535 6285815808 "GET /static/img/theme/material.jpg HTTP/1.1" 200 28774
+INFO 2025-09-07 15:03:50,514 basehttp 23535 6201683968 "GET /static/img/version/html.jpg HTTP/1.1" 200 17325
+INFO 2025-09-07 15:03:50,514 basehttp 23535 6218510336 "GET /static/img/theme/google.jpg HTTP/1.1" 200 86013
+INFO 2025-09-07 15:03:50,515 basehttp 23535 6268989440 "GET /static/img/version/ajax.jpg HTTP/1.1" 200 20223
+INFO 2025-09-07 15:03:50,515 basehttp 23535 6285815808 "GET /static/img/version/angular1x.jpg HTTP/1.1" 200 22869
+INFO 2025-09-07 15:03:50,517 basehttp 23535 6268989440 "GET /static/img/version/laravel.jpg HTTP/1.1" 200 26040
+INFO 2025-09-07 15:03:50,518 basehttp 23535 6218510336 "GET /static/img/version/angular10x.jpg HTTP/1.1" 200 24580
+INFO 2025-09-07 15:03:50,518 basehttp 23535 6285815808 "GET /static/img/version/django.jpg HTTP/1.1" 200 20935
+INFO 2025-09-07 15:03:50,518 basehttp 23535 6252163072 "GET /static/webfonts/fa-solid-900.woff2 HTTP/1.1" 200 158220
+INFO 2025-09-07 15:03:50,518 basehttp 23535 6201683968 "GET /static/img/version/svelte.jpg HTTP/1.1" 200 25060
+INFO 2025-09-07 15:03:50,520 basehttp 23535 6285815808 "GET /static/img/version/vuejs.jpg HTTP/1.1" 200 22518
+INFO 2025-09-07 15:03:50,521 basehttp 23535 6252163072 "GET /static/img/version/dotnet.jpg HTTP/1.1" 200 24791
+INFO 2025-09-07 15:03:50,522 basehttp 23535 6201683968 "GET /static/img/version/reactjs.jpg HTTP/1.1" 200 26850
+INFO 2025-09-07 15:03:50,523 basehttp 23535 6235336704 "GET /static/img/theme/e-commerce.jpg HTTP/1.1" 200 37734
+INFO 2025-09-07 15:03:50,523 basehttp 23535 6268989440 "GET /static/img/theme/one-page-parallax.jpg HTTP/1.1" 200 22474
+INFO 2025-09-07 15:03:50,523 basehttp 23535 6218510336 "GET /static/img/version/nextjs.jpg HTTP/1.1" 200 20152
+INFO 2025-09-07 15:03:50,523 basehttp 23535 6285815808 "GET /static/img/theme/blog.jpg HTTP/1.1" 200 32334
+INFO 2025-09-07 15:03:50,524 basehttp 23535 6252163072 "GET /static/img/theme/forum.jpg HTTP/1.1" 200 28744
+INFO 2025-09-07 15:03:50,524 basehttp 23535 6201683968 "GET /static/img/theme/corporate.jpg HTTP/1.1" 200 38911
+INFO 2025-09-07 15:03:50,538 basehttp 23535 6201683968 "GET /static/plugins/chart.js/dist/chart.umd.js.map HTTP/1.1" 200 958364
+INFO 2025-09-07 15:03:50,548 basehttp 23535 6201683968 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+WARNING 2025-09-07 15:03:50,569 basehttp 23535 6201683968 "GET /static/img/user/default-avatar.jpg HTTP/1.1" 404 2008
+WARNING 2025-09-07 15:03:50,625 log 23535 6285815808 Not Found: /favicon.ico
+WARNING 2025-09-07 15:03:50,625 basehttp 23535 6285815808 "GET /favicon.ico HTTP/1.1" 404 2557
+WARNING 2025-09-07 15:03:59,502 basehttp 23535 6285815808 "GET /static/img/user/default-avatar.jpg HTTP/1.1" 404 2008
+WARNING 2025-09-07 15:04:07,948 basehttp 23535 6252163072 "GET /static/img/user/default-avatar.jpg HTTP/1.1" 404 2008
+INFO 2025-09-07 15:04:15,855 basehttp 23535 6268989440 "GET /en/hr/employees/27/ HTTP/1.1" 200 34730
+WARNING 2025-09-07 15:04:15,880 log 23535 6268989440 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 15:04:15,880 basehttp 23535 6268989440 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-07 15:04:15,943 basehttp 23535 6268989440 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+WARNING 2025-09-07 15:04:22,166 log 23535 6268989440 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 15:04:22,166 basehttp 23535 6268989440 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+WARNING 2025-09-07 15:04:22,204 log 23535 6268989440 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 15:04:22,204 basehttp 23535 6268989440 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-07 15:04:50,563 basehttp 23535 6268989440 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 15:05:15,546 basehttp 23535 6268989440 "GET /en/hr/schedules/21/ HTTP/1.1" 200 173472
+WARNING 2025-09-07 15:05:15,555 basehttp 23535 6268989440 "GET /static/img/user/default-avatar.jpg HTTP/1.1" 404 2008
+WARNING 2025-09-07 15:05:15,567 basehttp 23535 6218510336 "GET /static/img/user/default-avatar.jpg HTTP/1.1" 404 2008
+WARNING 2025-09-07 15:05:15,571 log 23535 6235336704 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 15:05:15,571 basehttp 23535 6235336704 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-07 15:05:15,643 basehttp 23535 6235336704 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+WARNING 2025-09-07 15:05:15,665 basehttp 23535 6235336704 "GET /static/img/user/default-avatar.jpg HTTP/1.1" 404 2008
+WARNING 2025-09-07 15:05:44,464 basehttp 23535 6201683968 "GET /static/img/user/default-avatar.jpg HTTP/1.1" 404 2008
+INFO 2025-09-07 15:06:02,782 basehttp 23535 6201683968 "GET /en/hr/schedules/?page=2 HTTP/1.1" 200 123257
+INFO 2025-09-07 15:06:02,791 basehttp 23535 6201683968 "GET /static/plugins/moment/min/moment.min.js HTTP/1.1" 200 58890
+WARNING 2025-09-07 15:06:02,812 log 23535 6201683968 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 15:06:02,812 basehttp 23535 6201683968 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-07 15:06:02,819 basehttp 23535 6201683968 "GET /static/plugins/moment/min/moment.min.js.map HTTP/1.1" 200 98730
+INFO 2025-09-07 15:06:18,524 basehttp 23535 6201683968 "GET /en/hr/schedules/ HTTP/1.1" 200 122042
+WARNING 2025-09-07 15:06:18,548 log 23535 6201683968 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 15:06:18,548 basehttp 23535 6201683968 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-07 15:06:18,986 basehttp 23535 6201683968 "GET /en/hr/ HTTP/1.1" 200 42394
+WARNING 2025-09-07 15:06:19,008 log 23535 6201683968 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 15:06:19,008 basehttp 23535 6201683968 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-07 15:06:21,734 basehttp 23535 6201683968 "GET /en/hr/departments/ HTTP/1.1" 200 125426
+INFO 2025-09-07 15:06:21,750 basehttp 23535 6201683968 "GET /static/plugins/datatables.net-buttons-bs5/css/buttons.bootstrap5.min.css HTTP/1.1" 200 8136
+INFO 2025-09-07 15:06:21,750 basehttp 23535 6252163072 "GET /static/plugins/datatables.net-buttons-bs5/js/buttons.bootstrap5.min.js HTTP/1.1" 200 1627
+INFO 2025-09-07 15:06:21,751 basehttp 23535 6218510336 "GET /static/plugins/select2/dist/css/select2.min.css HTTP/1.1" 200 14966
+INFO 2025-09-07 15:06:21,751 basehttp 23535 6235336704 "GET /static/plugins/datatables.net-buttons/js/dataTables.buttons.min.js HTTP/1.1" 200 27926
+WARNING 2025-09-07 15:06:21,755 log 23535 6268989440 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 15:06:21,756 basehttp 23535 6268989440 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-07 15:06:21,758 basehttp 23535 6235336704 "GET /static/plugins/datatables.net-buttons/js/buttons.print.min.js HTTP/1.1" 200 3073
+INFO 2025-09-07 15:06:21,758 basehttp 23535 6218510336 "GET /static/plugins/datatables.net-buttons/js/buttons.html5.min.js HTTP/1.1" 200 26043
+INFO 2025-09-07 15:06:21,760 basehttp 23535 6201683968 "GET /static/plugins/jszip/dist/jszip.min.js HTTP/1.1" 200 97630
+INFO 2025-09-07 15:06:21,763 basehttp 23535 6268989440 "GET /static/plugins/select2/dist/js/select2.min.js HTTP/1.1" 200 70851
+INFO 2025-09-07 15:06:21,768 basehttp 23535 6285815808 "GET /static/plugins/pdfmake/build/vfs_fonts.js HTTP/1.1" 200 828866
+INFO 2025-09-07 15:06:21,769 basehttp 23535 6252163072 "GET /static/plugins/pdfmake/build/pdfmake.min.js HTTP/1.1" 200 1400771
+INFO 2025-09-07 15:06:21,851 basehttp 23535 6252163072 "GET /static/plugins/pdfmake/build/pdfmake.min.js.map HTTP/1.1" 200 4214503
+INFO 2025-09-07 15:06:21,853 basehttp 23535 6285815808 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+WARNING 2025-09-07 15:06:24,044 log 23535 6285815808 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 15:06:24,044 basehttp 23535 6285815808 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+WARNING 2025-09-07 15:06:24,058 log 23535 6285815808 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 15:06:24,058 basehttp 23535 6285815808 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+ERROR 2025-09-07 15:06:25,465 log 23535 6285815808 Internal Server Error: /en/hr/time-entries/
+Traceback (most recent call last):
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/core/handlers/exception.py", line 55, in inner
+ response = get_response(request)
+ ^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/core/handlers/base.py", line 220, in _get_response
+ response = response.render()
+ ^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/response.py", line 114, in render
+ self.content = self.rendered_content
+ ^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/response.py", line 92, in rendered_content
+ return template.render(context, self._request)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/backends/django.py", line 107, in render
+ return self.template.render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 171, in render
+ return self._render(context)
+ ^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 163, in _render
+ return self.nodelist.render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 1016, in render
+ return SafeString("".join([node.render_annotated(context) for node in self]))
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 977, in render_annotated
+ return self.render(context)
+ ^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/loader_tags.py", line 159, in render
+ return compiled_parent._render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 163, in _render
+ return self.nodelist.render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 1016, in render
+ return SafeString("".join([node.render_annotated(context) for node in self]))
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 977, in render_annotated
+ return self.render(context)
+ ^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/loader_tags.py", line 65, in render
+ result = block.nodelist.render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 1016, in render
+ return SafeString("".join([node.render_annotated(context) for node in self]))
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 977, in render_annotated
+ return self.render(context)
+ ^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/defaulttags.py", line 480, in render
+ url = reverse(view_name, args=args, kwargs=kwargs, current_app=current_app)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/urls/base.py", line 98, in reverse
+ resolved_url = resolver._reverse_with_prefix(view, prefix, *args, **kwargs)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/urls/resolvers.py", line 831, in _reverse_with_prefix
+ raise NoReverseMatch(msg)
+django.urls.exceptions.NoReverseMatch: Reverse for 'export_time_entries' not found. 'export_time_entries' is not a valid view function or pattern name.
+ERROR 2025-09-07 15:06:25,466 basehttp 23535 6285815808 "GET /en/hr/time-entries/ HTTP/1.1" 500 202728
+WARNING 2025-09-07 15:06:25,492 log 23535 6285815808 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 15:06:25,492 basehttp 23535 6285815808 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-07 15:07:32,068 basehttp 23535 6285815808 "GET /en/hr/time-entries/ HTTP/1.1" 200 143885
+WARNING 2025-09-07 15:07:32,077 basehttp 23535 6268989440 "GET /static/img/user/default-avatar.jpg HTTP/1.1" 404 2008
+INFO 2025-09-07 15:07:32,078 basehttp 23535 6252163072 "GET /static/plugins/bootstrap-daterangepicker/daterangepicker.css HTTP/1.1" 200 8069
+INFO 2025-09-07 15:07:32,079 basehttp 23535 6201683968 "GET /static/plugins/bootstrap-daterangepicker/daterangepicker.js HTTP/1.1" 200 67842
+WARNING 2025-09-07 15:07:32,081 log 23535 6285815808 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 15:07:32,081 basehttp 23535 6285815808 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+WARNING 2025-09-07 15:07:32,106 basehttp 23535 6285815808 "GET /static/img/user/default-avatar.jpg HTTP/1.1" 404 2008
+INFO 2025-09-07 15:07:32,138 basehttp 23535 6201683968 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+WARNING 2025-09-07 15:07:32,182 basehttp 23535 6201683968 "GET /static/img/user/default-avatar.jpg HTTP/1.1" 404 2008
+INFO 2025-09-07 15:07:50,766 basehttp 23535 6252163072 "GET /en/hr/time-entries/ HTTP/1.1" 200 143725
+WARNING 2025-09-07 15:07:50,774 basehttp 23535 6252163072 "GET /static/img/user/default-avatar.jpg HTTP/1.1" 404 2008
+INFO 2025-09-07 15:07:50,775 basehttp 23535 6218510336 "GET /static/img/user/user-1.jpg HTTP/1.1" 200 3528
+WARNING 2025-09-07 15:07:50,780 log 23535 6235336704 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 15:07:50,780 basehttp 23535 6235336704 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-07 15:07:50,837 basehttp 23535 6235336704 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+WARNING 2025-09-07 15:07:50,870 basehttp 23535 6235336704 "GET /static/img/user/default-avatar.jpg HTTP/1.1" 404 2008
+INFO 2025-09-07 15:07:52,889 basehttp 23535 6218510336 "GET /en/hr/time-entries/ HTTP/1.1" 200 143725
+INFO 2025-09-07 15:07:52,899 basehttp 23535 6235336704 "GET /static/css/custom.css HTTP/1.1" 200 2063
+INFO 2025-09-07 15:07:52,899 basehttp 23535 6252163072 "GET /static/plugins/datatables.net-bs5/css/dataTables.bootstrap5.min.css HTTP/1.1" 200 15096
+INFO 2025-09-07 15:07:52,900 basehttp 23535 6268989440 "GET /static/plugins/datatables.net-responsive-bs5/css/responsive.bootstrap5.min.css HTTP/1.1" 200 6044
+INFO 2025-09-07 15:07:52,902 basehttp 23535 6285815808 "GET /static/plugins/bootstrap-daterangepicker/daterangepicker.css HTTP/1.1" 200 8069
+INFO 2025-09-07 15:07:52,904 basehttp 23535 6268989440 "GET /static/img/user/user-4.jpg HTTP/1.1" 200 5916
+WARNING 2025-09-07 15:07:52,906 basehttp 23535 6285815808 "GET /static/img/user/default-avatar.jpg HTTP/1.1" 404 2008
+INFO 2025-09-07 15:07:52,908 basehttp 23535 6218510336 "GET /static/css/vendor.min.css HTTP/1.1" 200 177466
+INFO 2025-09-07 15:07:52,909 basehttp 23535 6235336704 "GET /static/js/htmx.min.js HTTP/1.1" 200 50917
+INFO 2025-09-07 15:07:52,911 basehttp 23535 6235336704 "GET /static/plugins/datatables.net-bs5/js/dataTables.bootstrap5.min.js HTTP/1.1" 200 1470
+WARNING 2025-09-07 15:07:52,913 log 23535 6252163072 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 15:07:52,913 basehttp 23535 6252163072 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-07 15:07:52,915 basehttp 23535 6235336704 "GET /static/plugins/datatables.net-responsive/js/dataTables.responsive.min.js HTTP/1.1" 200 16086
+INFO 2025-09-07 15:07:52,916 basehttp 23535 6285815808 "GET /static/plugins/datatables.net-responsive-bs5/js/responsive.bootstrap5.min.js HTTP/1.1" 200 1796
+INFO 2025-09-07 15:07:52,917 basehttp 23535 6252163072 - Broken pipe from ('127.0.0.1', 58254)
+INFO 2025-09-07 15:07:52,918 basehttp 23535 6218510336 "GET /static/plugins/datatables.net/js/dataTables.min.js HTTP/1.1" 200 95735
+INFO 2025-09-07 15:07:52,919 basehttp 23535 6302642176 "GET /static/js/app.min.js HTTP/1.1" 200 110394
+INFO 2025-09-07 15:07:52,922 basehttp 23535 6302642176 "GET /static/img/user/user-1.jpg HTTP/1.1" 200 3528
+INFO 2025-09-07 15:07:52,922 basehttp 23535 6235336704 "GET /static/plugins/moment/min/moment.min.js HTTP/1.1" 200 58890
+INFO 2025-09-07 15:07:52,922 basehttp 23535 6285815808 "GET /static/plugins/bootstrap-daterangepicker/daterangepicker.js HTTP/1.1" 200 67842
+INFO 2025-09-07 15:07:52,923 basehttp 23535 6218510336 "GET /static/plugins/select2/dist/js/select2.min.js HTTP/1.1" 200 70851
+INFO 2025-09-07 15:07:52,928 basehttp 23535 6201683968 "GET /static/css/default/app.min.css HTTP/1.1" 200 893480
+INFO 2025-09-07 15:07:52,929 basehttp 23535 6268989440 "GET /static/js/vendor.min.js HTTP/1.1" 200 1091361
+WARNING 2025-09-07 15:07:53,743 basehttp 23535 6268989440 "GET /static/img/user/default-avatar.jpg HTTP/1.1" 404 2008
+INFO 2025-09-07 15:07:53,773 basehttp 23535 6285815808 "GET /static/img/theme/apple.jpg HTTP/1.1" 200 28822
+INFO 2025-09-07 15:07:53,773 basehttp 23535 6201683968 "GET /static/img/theme/default.jpg HTTP/1.1" 200 26964
+INFO 2025-09-07 15:07:53,773 basehttp 23535 6302642176 "GET /static/img/theme/facebook.jpg HTTP/1.1" 200 27881
+INFO 2025-09-07 15:07:53,774 basehttp 23535 6235336704 "GET /static/img/theme/material.jpg HTTP/1.1" 200 28774
+INFO 2025-09-07 15:07:53,774 basehttp 23535 6218510336 "GET /static/img/theme/transparent.jpg HTTP/1.1" 200 32747
+INFO 2025-09-07 15:07:53,777 basehttp 23535 6235336704 "GET /static/img/version/ajax.jpg HTTP/1.1" 200 20223
+INFO 2025-09-07 15:07:53,778 basehttp 23535 6252163072 "GET /static/img/theme/google.jpg HTTP/1.1" 200 86013
+INFO 2025-09-07 15:07:53,778 basehttp 23535 6218510336 "GET /static/img/version/angular1x.jpg HTTP/1.1" 200 22869
+INFO 2025-09-07 15:07:53,778 basehttp 23535 6302642176 "GET /static/img/version/html.jpg HTTP/1.1" 200 17325
+INFO 2025-09-07 15:07:53,779 basehttp 23535 6201683968 "GET /static/img/version/angular10x.jpg HTTP/1.1" 200 24580
+INFO 2025-09-07 15:07:53,781 basehttp 23535 6235336704 "GET /static/img/version/svelte.jpg HTTP/1.1" 200 25060
+INFO 2025-09-07 15:07:53,781 basehttp 23535 6252163072 "GET /static/img/version/laravel.jpg HTTP/1.1" 200 26040
+INFO 2025-09-07 15:07:53,782 basehttp 23535 6302642176 "GET /static/img/version/vuejs.jpg HTTP/1.1" 200 22518
+INFO 2025-09-07 15:07:53,782 basehttp 23535 6218510336 "GET /static/img/version/django.jpg HTTP/1.1" 200 20935
+INFO 2025-09-07 15:07:53,782 basehttp 23535 6201683968 "GET /static/img/version/reactjs.jpg HTTP/1.1" 200 26850
+INFO 2025-09-07 15:07:53,782 basehttp 23535 6285815808 "GET /static/webfonts/fa-solid-900.woff2 HTTP/1.1" 200 158220
+INFO 2025-09-07 15:07:53,785 basehttp 23535 6201683968 "GET /static/img/theme/blog.jpg HTTP/1.1" 200 32334
+INFO 2025-09-07 15:07:53,785 basehttp 23535 6235336704 "GET /static/img/version/nextjs.jpg HTTP/1.1" 200 20152
+INFO 2025-09-07 15:07:53,785 basehttp 23535 6218510336 "GET /static/img/theme/one-page-parallax.jpg HTTP/1.1" 200 22474
+INFO 2025-09-07 15:07:53,785 basehttp 23535 6302642176 "GET /static/img/theme/e-commerce.jpg HTTP/1.1" 200 37734
+INFO 2025-09-07 15:07:53,785 basehttp 23535 6252163072 "GET /static/img/version/dotnet.jpg HTTP/1.1" 200 24791
+INFO 2025-09-07 15:07:53,786 basehttp 23535 6285815808 "GET /static/img/theme/forum.jpg HTTP/1.1" 200 28744
+INFO 2025-09-07 15:07:53,786 basehttp 23535 6201683968 "GET /static/img/theme/corporate.jpg HTTP/1.1" 200 38911
+INFO 2025-09-07 15:07:53,796 basehttp 23535 6201683968 "GET /static/css/default/app.min.css.map HTTP/1.1" 200 1957526
+INFO 2025-09-07 15:07:53,806 basehttp 23535 6201683968 "GET /static/plugins/moment/min/moment.min.js.map HTTP/1.1" 200 98730
+INFO 2025-09-07 15:07:53,819 basehttp 23535 6201683968 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+WARNING 2025-09-07 15:07:53,855 basehttp 23535 6201683968 "GET /static/img/user/default-avatar.jpg HTTP/1.1" 404 2008
+WARNING 2025-09-07 15:07:54,101 log 23535 6302642176 Not Found: /favicon.ico
+WARNING 2025-09-07 15:07:54,101 basehttp 23535 6302642176 "GET /favicon.ico HTTP/1.1" 404 2557
+INFO 2025-09-07 15:08:41,055 basehttp 23535 6302642176 "GET /en/hr/time-entries/ HTTP/1.1" 200 138936
+WARNING 2025-09-07 15:08:41,068 log 23535 6302642176 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 15:08:41,068 basehttp 23535 6302642176 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-07 15:08:41,164 basehttp 23535 6302642176 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 15:08:54,359 basehttp 23535 6302642176 "GET /en/hr/time-entries/ HTTP/1.1" 200 138956
+INFO 2025-09-07 15:08:54,366 basehttp 23535 6302642176 "GET /static/img/user/user-10.jpg HTTP/1.1" 200 6490
+WARNING 2025-09-07 15:08:54,374 log 23535 6302642176 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 15:08:54,374 basehttp 23535 6302642176 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-07 15:08:54,431 basehttp 23535 6302642176 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 15:09:16,424 basehttp 23535 6302642176 "GET /en/hr/time-entries/ HTTP/1.1" 200 137743
+WARNING 2025-09-07 15:09:16,439 log 23535 6302642176 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 15:09:16,439 basehttp 23535 6302642176 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-07 15:09:16,498 basehttp 23535 6302642176 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 15:09:31,143 basehttp 23535 6302642176 "GET /en/hr/time-entries/ HTTP/1.1" 200 137863
+WARNING 2025-09-07 15:09:31,156 log 23535 6302642176 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 15:09:31,156 basehttp 23535 6302642176 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-07 15:09:31,207 basehttp 23535 6302642176 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 15:10:03,173 basehttp 23535 6302642176 "GET /en/hr/time-entries/ HTTP/1.1" 200 138243
+WARNING 2025-09-07 15:10:03,188 log 23535 6302642176 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 15:10:03,188 basehttp 23535 6302642176 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-07 15:10:03,237 basehttp 23535 6302642176 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 15:10:43,104 basehttp 23535 6302642176 "GET /en/hr/time-entries/ HTTP/1.1" 200 137710
+WARNING 2025-09-07 15:10:43,121 log 23535 6302642176 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 15:10:43,121 basehttp 23535 6302642176 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-07 15:10:43,175 basehttp 23535 6302642176 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 15:10:47,796 basehttp 23535 6302642176 "GET /en/hr/time-entries/45/ HTTP/1.1" 200 32196
+WARNING 2025-09-07 15:10:47,807 basehttp 23535 6285815808 "GET /static/img/user/default-avatar.jpg HTTP/1.1" 404 2008
+WARNING 2025-09-07 15:10:47,812 log 23535 6302642176 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 15:10:47,812 basehttp 23535 6302642176 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-07 15:10:47,857 basehttp 23535 6302642176 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 15:11:17,487 basehttp 23535 6302642176 "GET /en/hr/time-entries/45/ HTTP/1.1" 200 32165
+WARNING 2025-09-07 15:11:17,500 basehttp 23535 6302642176 "GET /static/img/user/default-avatar.jpg HTTP/1.1" 404 2008
+WARNING 2025-09-07 15:11:17,508 log 23535 6252163072 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 15:11:17,508 basehttp 23535 6252163072 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-07 15:11:17,554 basehttp 23535 6252163072 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 15:11:37,340 basehttp 23535 6252163072 "GET /en/hr/time-entries/45/ HTTP/1.1" 200 32158
+WARNING 2025-09-07 15:11:37,359 log 23535 6252163072 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 15:11:37,359 basehttp 23535 6252163072 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-07 15:11:37,404 basehttp 23535 6252163072 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 15:11:41,289 basehttp 23535 6252163072 "GET /en/hr/employees/2/ HTTP/1.1" 200 34735
+WARNING 2025-09-07 15:11:41,309 log 23535 6252163072 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 15:11:41,309 basehttp 23535 6252163072 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-07 15:11:41,351 basehttp 23535 6252163072 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+WARNING 2025-09-07 15:11:43,657 log 23535 6252163072 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 15:11:43,657 basehttp 23535 6252163072 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+WARNING 2025-09-07 15:11:43,668 log 23535 6252163072 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 15:11:43,668 basehttp 23535 6252163072 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-07 15:12:25,801 basehttp 23535 6252163072 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+WARNING 2025-09-07 15:12:25,802 log 23535 6218510336 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 15:12:25,802 basehttp 23535 6218510336 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+WARNING 2025-09-07 15:12:25,816 log 23535 6218510336 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 15:12:25,817 basehttp 23535 6218510336 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-07 15:12:27,914 basehttp 23535 6218510336 "GET /en/hr/ HTTP/1.1" 200 42394
+WARNING 2025-09-07 15:12:27,929 log 23535 6218510336 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 15:12:27,929 basehttp 23535 6218510336 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-07 15:12:30,289 basehttp 23535 6218510336 "GET /en/hr/employees/ HTTP/1.1" 200 130495
+WARNING 2025-09-07 15:12:30,308 log 23535 6218510336 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 15:12:30,308 basehttp 23535 6218510336 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-07 15:12:30,330 basehttp 23535 6218510336 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+ERROR 2025-09-07 15:12:32,887 log 23535 6218510336 Internal Server Error: /en/hr/employees/56/delete/
+Traceback (most recent call last):
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/core/handlers/exception.py", line 55, in inner
+ response = get_response(request)
+ ^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/core/handlers/base.py", line 220, in _get_response
+ response = response.render()
+ ^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/response.py", line 114, in render
+ self.content = self.rendered_content
+ ^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/response.py", line 92, in rendered_content
+ return template.render(context, self._request)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/backends/django.py", line 107, in render
+ return self.template.render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 171, in render
+ return self._render(context)
+ ^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 163, in _render
+ return self.nodelist.render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 1016, in render
+ return SafeString("".join([node.render_annotated(context) for node in self]))
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 977, in render_annotated
+ return self.render(context)
+ ^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/loader_tags.py", line 159, in render
+ return compiled_parent._render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 163, in _render
+ return self.nodelist.render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 1016, in render
+ return SafeString("".join([node.render_annotated(context) for node in self]))
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 977, in render_annotated
+ return self.render(context)
+ ^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/loader_tags.py", line 65, in render
+ result = block.nodelist.render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 1016, in render
+ return SafeString("".join([node.render_annotated(context) for node in self]))
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 977, in render_annotated
+ return self.render(context)
+ ^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/defaulttags.py", line 480, in render
+ url = reverse(view_name, args=args, kwargs=kwargs, current_app=current_app)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/urls/base.py", line 98, in reverse
+ resolved_url = resolver._reverse_with_prefix(view, prefix, *args, **kwargs)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/urls/resolvers.py", line 831, in _reverse_with_prefix
+ raise NoReverseMatch(msg)
+django.urls.exceptions.NoReverseMatch: Reverse for 'employee_deactivate' not found. 'employee_deactivate' is not a valid view function or pattern name.
+ERROR 2025-09-07 15:12:32,888 basehttp 23535 6218510336 "GET /en/hr/employees/56/delete/ HTTP/1.1" 500 174783
+WARNING 2025-09-07 15:12:32,907 log 23535 6218510336 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 15:12:32,907 basehttp 23535 6218510336 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-07 15:14:32,943 autoreload 23535 8747049152 /Users/marwanalwali/manus_project/hospital_management_system_v4/hr/views.py changed, reloading.
+INFO 2025-09-07 15:14:33,479 autoreload 36795 8747049152 Watching for file changes with StatReloader
+INFO 2025-09-07 15:14:34,155 basehttp 36795 6341865472 "GET /en/hr/employees/56/delete/ HTTP/1.1" 200 34468
+WARNING 2025-09-07 15:14:34,174 log 36795 6341865472 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 15:14:34,174 basehttp 36795 6341865472 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-07 15:14:34,222 basehttp 36795 6341865472 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 15:15:01,587 basehttp 36795 6341865472 "GET /en/hr/employees/56/ HTTP/1.1" 200 34482
+WARNING 2025-09-07 15:15:01,601 log 36795 6341865472 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 15:15:01,601 basehttp 36795 6341865472 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-07 15:15:01,638 basehttp 36795 6341865472 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+WARNING 2025-09-07 15:15:43,738 log 36795 6358691840 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 15:15:43,739 basehttp 36795 6358691840 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-07 15:15:43,741 basehttp 36795 6341865472 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+WARNING 2025-09-07 15:15:43,746 log 36795 6358691840 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 15:15:43,746 basehttp 36795 6358691840 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-07 15:15:50,386 basehttp 36795 6358691840 "GET /en/hr/employees/ HTTP/1.1" 200 130495
+WARNING 2025-09-07 15:15:50,398 log 36795 6358691840 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 15:15:50,398 basehttp 36795 6358691840 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-07 15:15:50,444 basehttp 36795 6358691840 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+WARNING 2025-09-07 15:16:18,096 log 36795 6358691840 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 15:16:18,097 basehttp 36795 6358691840 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+WARNING 2025-09-07 15:16:18,109 log 36795 6358691840 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 15:16:18,109 basehttp 36795 6358691840 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-07 15:16:20,480 basehttp 36795 6358691840 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+WARNING 2025-09-07 15:16:20,481 log 36795 6341865472 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 15:16:20,481 basehttp 36795 6341865472 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+WARNING 2025-09-07 15:16:20,490 log 36795 6341865472 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 15:16:20,490 basehttp 36795 6341865472 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-07 15:16:22,038 basehttp 36795 6341865472 "GET / HTTP/1.1" 302 0
+INFO 2025-09-07 15:16:22,063 basehttp 36795 6358691840 "GET /en/ HTTP/1.1" 200 49810
+WARNING 2025-09-07 15:16:22,083 log 36795 6358691840 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 15:16:22,083 basehttp 36795 6358691840 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-07 15:16:22,161 basehttp 36795 6358691840 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 15:16:22,164 basehttp 36795 6392344576 "GET /en/htmx/tenant-info/ HTTP/1.1" 200 1043
+INFO 2025-09-07 15:16:22,165 basehttp 36795 6375518208 "GET /en/htmx/system-health/ HTTP/1.1" 200 1356
+INFO 2025-09-07 15:16:22,168 basehttp 36795 6341865472 "GET /en/htmx/dashboard-stats/ HTTP/1.1" 200 2094
+INFO 2025-09-07 15:16:30,883 basehttp 36795 6341865472 "GET /en/hr HTTP/1.1" 301 0
+INFO 2025-09-07 15:16:30,921 basehttp 36795 6375518208 "GET /en/hr/ HTTP/1.1" 200 42394
+WARNING 2025-09-07 15:16:30,938 log 36795 6375518208 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 15:16:30,938 basehttp 36795 6375518208 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-07 15:16:30,956 basehttp 36795 6375518208 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+ERROR 2025-09-07 15:16:39,629 log 36795 6375518208 Internal Server Error: /en/hr/reviews/
+Traceback (most recent call last):
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/core/handlers/exception.py", line 55, in inner
+ response = get_response(request)
+ ^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/core/handlers/base.py", line 220, in _get_response
+ response = response.render()
+ ^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/response.py", line 114, in render
+ self.content = self.rendered_content
+ ^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/response.py", line 92, in rendered_content
+ return template.render(context, self._request)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/backends/django.py", line 107, in render
+ return self.template.render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 171, in render
+ return self._render(context)
+ ^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 163, in _render
+ return self.nodelist.render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 1016, in render
+ return SafeString("".join([node.render_annotated(context) for node in self]))
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 977, in render_annotated
+ return self.render(context)
+ ^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/loader_tags.py", line 159, in render
+ return compiled_parent._render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 163, in _render
+ return self.nodelist.render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 1016, in render
+ return SafeString("".join([node.render_annotated(context) for node in self]))
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 977, in render_annotated
+ return self.render(context)
+ ^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/loader_tags.py", line 65, in render
+ result = block.nodelist.render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 1016, in render
+ return SafeString("".join([node.render_annotated(context) for node in self]))
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 977, in render_annotated
+ return self.render(context)
+ ^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/defaulttags.py", line 480, in render
+ url = reverse(view_name, args=args, kwargs=kwargs, current_app=current_app)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/urls/base.py", line 98, in reverse
+ resolved_url = resolver._reverse_with_prefix(view, prefix, *args, **kwargs)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/urls/resolvers.py", line 831, in _reverse_with_prefix
+ raise NoReverseMatch(msg)
+django.urls.exceptions.NoReverseMatch: Reverse for 'export_performance_reviews' not found. 'export_performance_reviews' is not a valid view function or pattern name.
+ERROR 2025-09-07 15:16:39,630 basehttp 36795 6375518208 "GET /en/hr/reviews/ HTTP/1.1" 500 213690
+WARNING 2025-09-07 15:16:39,650 log 36795 6375518208 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 15:16:39,650 basehttp 36795 6375518208 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-07 15:17:34,224 basehttp 36795 6375518208 "GET /en/hr/reviews/ HTTP/1.1" 200 37449
+WARNING 2025-09-07 15:17:34,238 log 36795 6375518208 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 15:17:34,239 basehttp 36795 6375518208 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-07 15:17:34,285 basehttp 36795 6375518208 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 15:18:34,298 basehttp 36795 6375518208 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 15:19:34,301 basehttp 36795 6375518208 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 15:19:34,844 basehttp 36795 6375518208 "GET /en/hr/reviews/ HTTP/1.1" 200 37356
+WARNING 2025-09-07 15:19:34,863 log 36795 6375518208 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 15:19:34,863 basehttp 36795 6375518208 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-07 15:19:34,913 basehttp 36795 6375518208 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 15:20:00,885 basehttp 36795 6375518208 "GET /en/hr/reviews/ HTTP/1.1" 200 37346
+WARNING 2025-09-07 15:20:00,902 log 36795 6375518208 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 15:20:00,902 basehttp 36795 6375518208 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-07 15:20:00,951 basehttp 36795 6375518208 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 15:20:15,335 basehttp 36795 6375518208 "GET /en/hr/reviews/ HTTP/1.1" 200 37343
+WARNING 2025-09-07 15:20:15,355 log 36795 6375518208 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 15:20:15,355 basehttp 36795 6375518208 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-07 15:20:15,406 basehttp 36795 6375518208 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 15:20:18,213 basehttp 36795 6375518208 "GET /en/hr/reviews/ HTTP/1.1" 200 37343
+INFO 2025-09-07 15:20:18,226 basehttp 36795 6425997312 "GET /static/plugins/bootstrap-daterangepicker/daterangepicker.css HTTP/1.1" 200 8069
+INFO 2025-09-07 15:20:18,227 basehttp 36795 6409170944 "GET /static/plugins/datatables.net-responsive-bs5/css/responsive.bootstrap5.min.css HTTP/1.1" 200 6044
+INFO 2025-09-07 15:20:18,227 basehttp 36795 6358691840 "GET /static/css/custom.css HTTP/1.1" 200 2063
+INFO 2025-09-07 15:20:18,228 basehttp 36795 6341865472 "GET /static/plugins/datatables.net-bs5/css/dataTables.bootstrap5.min.css HTTP/1.1" 200 15096
+INFO 2025-09-07 15:20:18,230 basehttp 36795 6425997312 "GET /static/js/htmx.min.js HTTP/1.1" 200 50917
+INFO 2025-09-07 15:20:18,232 basehttp 36795 6375518208 "GET /static/css/vendor.min.css HTTP/1.1" 200 177466
+WARNING 2025-09-07 15:20:18,234 log 36795 6409170944 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+INFO 2025-09-07 15:20:18,235 basehttp 36795 6392344576 "GET /static/css/default/app.min.css HTTP/1.1" 200 893480
+WARNING 2025-09-07 15:20:18,237 basehttp 36795 6409170944 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-07 15:20:18,419 basehttp 36795 6392344576 "GET /static/img/user/user-4.jpg HTTP/1.1" 200 5916
+INFO 2025-09-07 15:20:18,422 basehttp 36795 6392344576 "GET /static/js/app.min.js HTTP/1.1" 200 110394
+INFO 2025-09-07 15:20:18,425 basehttp 36795 6409170944 "GET /static/js/vendor.min.js HTTP/1.1" 200 1091361
+INFO 2025-09-07 15:20:18,427 basehttp 36795 6409170944 "GET /static/plugins/datatables.net-bs5/js/dataTables.bootstrap5.min.js HTTP/1.1" 200 1470
+INFO 2025-09-07 15:20:18,429 basehttp 36795 6409170944 "GET /static/plugins/datatables.net-responsive/js/dataTables.responsive.min.js HTTP/1.1" 200 16086
+INFO 2025-09-07 15:20:18,430 basehttp 36795 6392344576 "GET /static/plugins/datatables.net/js/dataTables.min.js HTTP/1.1" 200 95735
+INFO 2025-09-07 15:20:18,430 basehttp 36795 6409170944 "GET /static/plugins/datatables.net-responsive-bs5/js/responsive.bootstrap5.min.js HTTP/1.1" 200 1796
+INFO 2025-09-07 15:20:18,432 basehttp 36795 6392344576 "GET /static/plugins/moment/min/moment.min.js HTTP/1.1" 200 58890
+INFO 2025-09-07 15:20:18,432 basehttp 36795 6409170944 "GET /static/plugins/bootstrap-daterangepicker/daterangepicker.js HTTP/1.1" 200 67842
+INFO 2025-09-07 15:20:18,435 basehttp 36795 6392344576 "GET /static/plugins/select2/dist/js/select2.min.js HTTP/1.1" 200 70851
+INFO 2025-09-07 15:20:19,239 basehttp 36795 6409170944 "GET /static/img/theme/transparent.jpg HTTP/1.1" 200 32747
+INFO 2025-09-07 15:20:19,239 basehttp 36795 6341865472 "GET /static/img/theme/facebook.jpg HTTP/1.1" 200 27881
+INFO 2025-09-07 15:20:19,239 basehttp 36795 6392344576 "GET /static/img/theme/default.jpg HTTP/1.1" 200 26964
+INFO 2025-09-07 15:20:19,239 basehttp 36795 6375518208 "GET /static/img/theme/apple.jpg HTTP/1.1" 200 28822
+INFO 2025-09-07 15:20:19,239 basehttp 36795 6425997312 "GET /static/img/theme/material.jpg HTTP/1.1" 200 28774
+INFO 2025-09-07 15:20:19,243 basehttp 36795 6358691840 "GET /static/img/theme/google.jpg HTTP/1.1" 200 86013
+INFO 2025-09-07 15:20:19,243 basehttp 36795 6409170944 "GET /static/img/version/html.jpg HTTP/1.1" 200 17325
+INFO 2025-09-07 15:20:19,244 basehttp 36795 6341865472 "GET /static/img/version/angular1x.jpg HTTP/1.1" 200 22869
+INFO 2025-09-07 15:20:19,245 basehttp 36795 6392344576 "GET /static/img/version/ajax.jpg HTTP/1.1" 200 20223
+INFO 2025-09-07 15:20:19,245 basehttp 36795 6341865472 "GET /static/img/version/vuejs.jpg HTTP/1.1" 200 22518
+INFO 2025-09-07 15:20:19,245 basehttp 36795 6375518208 "GET /static/img/version/angular10x.jpg HTTP/1.1" 200 24580
+INFO 2025-09-07 15:20:19,246 basehttp 36795 6358691840 "GET /static/img/version/django.jpg HTTP/1.1" 200 20935
+INFO 2025-09-07 15:20:19,246 basehttp 36795 6425997312 "GET /static/img/version/svelte.jpg HTTP/1.1" 200 25060
+INFO 2025-09-07 15:20:19,247 basehttp 36795 6409170944 "GET /static/img/version/laravel.jpg HTTP/1.1" 200 26040
+INFO 2025-09-07 15:20:19,248 basehttp 36795 6392344576 "GET /static/img/version/reactjs.jpg HTTP/1.1" 200 26850
+INFO 2025-09-07 15:20:19,249 basehttp 36795 6358691840 "GET /static/img/version/dotnet.jpg HTTP/1.1" 200 24791
+INFO 2025-09-07 15:20:19,249 basehttp 36795 6375518208 "GET /static/img/theme/e-commerce.jpg HTTP/1.1" 200 37734
+INFO 2025-09-07 15:20:19,250 basehttp 36795 6341865472 "GET /static/img/theme/one-page-parallax.jpg HTTP/1.1" 200 22474
+INFO 2025-09-07 15:20:19,250 basehttp 36795 6409170944 "GET /static/img/theme/blog.jpg HTTP/1.1" 200 32334
+INFO 2025-09-07 15:20:19,250 basehttp 36795 6425997312 "GET /static/img/version/nextjs.jpg HTTP/1.1" 200 20152
+INFO 2025-09-07 15:20:19,252 basehttp 36795 6341865472 "GET /static/img/theme/forum.jpg HTTP/1.1" 200 28744
+INFO 2025-09-07 15:20:19,252 basehttp 36795 6375518208 "GET /static/img/theme/corporate.jpg HTTP/1.1" 200 38911
+INFO 2025-09-07 15:20:19,254 basehttp 36795 6392344576 "GET /static/webfonts/fa-solid-900.woff2 HTTP/1.1" 200 158220
+INFO 2025-09-07 15:20:19,261 basehttp 36795 6409170944 "GET /static/css/default/app.min.css.map HTTP/1.1" 200 1957526
+INFO 2025-09-07 15:20:19,295 basehttp 36795 6409170944 "GET /static/plugins/moment/min/moment.min.js.map HTTP/1.1" 200 98730
+INFO 2025-09-07 15:20:19,307 basehttp 36795 6409170944 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+WARNING 2025-09-07 15:20:19,537 log 36795 6409170944 Not Found: /favicon.ico
+WARNING 2025-09-07 15:20:19,537 basehttp 36795 6409170944 "GET /favicon.ico HTTP/1.1" 404 2557
+INFO 2025-09-07 15:20:32,844 basehttp 36795 6409170944 "GET /en/admin/hr/performancereview/ HTTP/1.1" 200 139984
+INFO 2025-09-07 15:20:32,855 basehttp 36795 6392344576 "GET /static/admin/css/dark_mode.css HTTP/1.1" 200 2808
+INFO 2025-09-07 15:20:32,856 basehttp 36795 6341865472 "GET /static/admin/css/nav_sidebar.css HTTP/1.1" 200 2810
+INFO 2025-09-07 15:20:32,856 basehttp 36795 6375518208 "GET /static/admin/js/theme.js HTTP/1.1" 200 1653
+INFO 2025-09-07 15:20:32,856 basehttp 36795 6409170944 "GET /static/admin/css/base.css HTTP/1.1" 200 22120
+INFO 2025-09-07 15:20:32,857 basehttp 36795 6425997312 "GET /static/admin/css/changelists.css HTTP/1.1" 200 6878
+INFO 2025-09-07 15:20:32,859 basehttp 36795 6375518208 "GET /static/admin/js/jquery.init.js HTTP/1.1" 200 347
+INFO 2025-09-07 15:20:32,860 basehttp 36795 6392344576 "GET /static/admin/css/responsive.css HTTP/1.1" 200 16565
+INFO 2025-09-07 15:20:32,860 basehttp 36795 6409170944 "GET /static/admin/js/core.js HTTP/1.1" 200 6208
+INFO 2025-09-07 15:20:32,860 basehttp 36795 6425997312 "GET /static/admin/js/admin/RelatedObjectLookups.js HTTP/1.1" 200 9777
+INFO 2025-09-07 15:20:32,863 basehttp 36795 6375518208 "GET /static/admin/js/actions.js HTTP/1.1" 200 8076
+INFO 2025-09-07 15:20:32,863 basehttp 36795 6409170944 "GET /static/admin/js/urlify.js HTTP/1.1" 200 7887
+INFO 2025-09-07 15:20:32,863 basehttp 36795 6392344576 "GET /static/admin/js/prepopulate.js HTTP/1.1" 200 1531
+INFO 2025-09-07 15:20:32,866 basehttp 36795 6341865472 "GET /static/admin/js/vendor/jquery/jquery.js HTTP/1.1" 200 285314
+INFO 2025-09-07 15:20:32,867 basehttp 36795 6392344576 "GET /static/admin/img/search.svg HTTP/1.1" 200 458
+INFO 2025-09-07 15:20:32,867 basehttp 36795 6358691840 "GET /en/admin/jsi18n/ HTTP/1.1" 200 3342
+INFO 2025-09-07 15:20:32,868 basehttp 36795 6358691840 "GET /static/admin/js/nav_sidebar.js HTTP/1.1" 200 3063
+INFO 2025-09-07 15:20:32,869 basehttp 36795 6425997312 "GET /static/admin/js/vendor/xregexp/xregexp.js HTTP/1.1" 200 325171
+INFO 2025-09-07 15:20:32,872 basehttp 36795 6425997312 "GET /static/admin/js/filters.js HTTP/1.1" 200 978
+INFO 2025-09-07 15:20:32,881 basehttp 36795 6425997312 "GET /static/admin/img/icon-addlink.svg HTTP/1.1" 200 331
+INFO 2025-09-07 15:20:32,881 basehttp 36795 6358691840 "GET /static/admin/img/tooltag-add.svg HTTP/1.1" 200 331
+INFO 2025-09-07 15:20:32,881 basehttp 36795 6392344576 "GET /static/admin/img/sorting-icons.svg HTTP/1.1" 200 1097
+INFO 2025-09-07 15:20:32,882 basehttp 36795 6392344576 "GET /static/admin/img/icon-viewlink.svg HTTP/1.1" 200 581
+INFO 2025-09-07 15:21:19,323 basehttp 36795 6392344576 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 15:21:56,623 autoreload 36795 8747049152 /Users/marwanalwali/manus_project/hospital_management_system_v4/hr/views.py changed, reloading.
+INFO 2025-09-07 15:21:57,093 autoreload 40099 8747049152 Watching for file changes with StatReloader
+INFO 2025-09-07 15:21:57,588 basehttp 40099 6170996736 "GET /en/hr/reviews/ HTTP/1.1" 200 87097
+WARNING 2025-09-07 15:21:57,604 log 40099 6170996736 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 15:21:57,604 basehttp 40099 6170996736 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-07 15:21:57,691 basehttp 40099 6170996736 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 15:22:22,149 basehttp 40099 6170996736 "GET /en/hr/reviews/ HTTP/1.1" 200 149783
+WARNING 2025-09-07 15:22:22,164 log 40099 6170996736 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 15:22:22,164 basehttp 40099 6170996736 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-07 15:22:22,221 basehttp 40099 6170996736 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 15:22:39,257 basehttp 40099 6170996736 "GET /en/hr/reviews/create/ HTTP/1.1" 200 51757
+INFO 2025-09-07 15:22:39,273 basehttp 40099 6187823104 "GET /static/plugins/select2/dist/css/select2.min.css HTTP/1.1" 200 14966
+WARNING 2025-09-07 15:22:39,275 log 40099 6170996736 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 15:22:39,276 basehttp 40099 6170996736 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-07 15:22:39,276 basehttp 40099 6204649472 "GET /static/plugins/summernote/dist/summernote-lite.css HTTP/1.1" 200 38212
+INFO 2025-09-07 15:22:39,277 basehttp 40099 6221475840 "GET /static/plugins/summernote/dist/summernote-lite.min.js HTTP/1.1" 200 186367
+INFO 2025-09-07 15:22:39,321 basehttp 40099 6221475840 "GET /static/webfonts/fa-regular-400.woff2 HTTP/1.1" 200 25472
+INFO 2025-09-07 15:22:39,329 basehttp 40099 6221475840 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 15:22:39,331 basehttp 40099 6221475840 "GET /static/plugins/summernote/dist/summernote-lite.css.map HTTP/1.1" 200 52049
+WARNING 2025-09-07 15:22:57,227 log 40099 6221475840 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 15:22:57,227 basehttp 40099 6221475840 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+WARNING 2025-09-07 15:22:57,261 log 40099 6221475840 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 15:22:57,261 basehttp 40099 6221475840 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-07 15:23:03,538 basehttp 40099 6221475840 "GET /en/hr/reviews/8/ HTTP/1.1" 200 35190
+WARNING 2025-09-07 15:23:03,557 basehttp 40099 6204649472 "GET /static/plugins/chart.js/dist/Chart.min.css HTTP/1.1" 404 2032
+WARNING 2025-09-07 15:23:03,558 basehttp 40099 6170996736 "GET /static/img/user/default-avatar.jpg HTTP/1.1" 404 2008
+WARNING 2025-09-07 15:23:03,559 basehttp 40099 6187823104 "GET /static/plugins/chart.js/dist/Chart.min.js HTTP/1.1" 404 2029
+WARNING 2025-09-07 15:23:03,561 log 40099 6221475840 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 15:23:03,561 basehttp 40099 6221475840 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+WARNING 2025-09-07 15:23:03,585 basehttp 40099 6221475840 "GET /static/img/user/default-avatar.jpg HTTP/1.1" 404 2008
+INFO 2025-09-07 15:23:03,604 basehttp 40099 6170996736 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 15:24:03,619 basehttp 40099 6170996736 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 15:25:03,623 basehttp 40099 6170996736 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 15:26:03,615 basehttp 40099 6170996736 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 15:27:03,639 basehttp 40099 6170996736 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 15:27:19,943 autoreload 40099 8747049152 /Users/marwanalwali/manus_project/hospital_management_system_v4/hr/models.py changed, reloading.
+INFO 2025-09-07 15:27:20,378 autoreload 42495 8747049152 Watching for file changes with StatReloader
+INFO 2025-09-07 15:28:03,695 basehttp 42495 6169866240 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 15:29:03,630 basehttp 42495 6169866240 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 15:29:15,762 autoreload 42495 8747049152 /Users/marwanalwali/manus_project/hospital_management_system_v4/hr/models.py changed, reloading.
+INFO 2025-09-07 15:29:16,265 autoreload 43350 8747049152 Watching for file changes with StatReloader
+INFO 2025-09-07 15:30:03,693 basehttp 43350 6196097024 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 15:31:03,637 basehttp 43350 6196097024 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 15:31:56,553 autoreload 43350 8747049152 /Users/marwanalwali/manus_project/hospital_management_system_v4/hr/views.py changed, reloading.
+INFO 2025-09-07 15:31:56,912 autoreload 44551 8747049152 Watching for file changes with StatReloader
+INFO 2025-09-07 15:32:03,696 basehttp 44551 6164459520 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 15:33:03,629 basehttp 44551 6164459520 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 15:34:03,634 basehttp 44551 6164459520 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 15:35:03,646 basehttp 44551 6164459520 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 15:36:03,647 basehttp 44551 6164459520 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 15:37:03,650 basehttp 44551 6164459520 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+ERROR 2025-09-07 15:37:37,753 log 44551 6164459520 Internal Server Error: /en/hr/reviews/8/
+Traceback (most recent call last):
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/core/handlers/exception.py", line 55, in inner
+ response = get_response(request)
+ ^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/core/handlers/base.py", line 197, in _get_response
+ response = wrapped_callback(request, *callback_args, **callback_kwargs)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/views/generic/base.py", line 105, in view
+ return self.dispatch(request, *args, **kwargs)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/contrib/auth/mixins.py", line 73, in dispatch
+ return super().dispatch(request, *args, **kwargs)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/views/generic/base.py", line 144, in dispatch
+ return handler(request, *args, **kwargs)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/views/generic/detail.py", line 112, in get
+ self.object = self.get_object()
+ ^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/hr/views.py", line 712, in get_object
+ return get_object_or_404(queryset, pk=self.kwargs.get(self.pk_url_kwarg, self.kwargs.get('pk')))
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/shortcuts.py", line 90, in get_object_or_404
+ return queryset.get(*args, **kwargs)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/db/models/query.py", line 629, in get
+ num = len(clone)
+ ^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/db/models/query.py", line 366, in __len__
+ self._fetch_all()
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/db/models/query.py", line 1949, in _fetch_all
+ self._result_cache = list(self._iterable_class(self))
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/db/models/query.py", line 91, in __iter__
+ results = compiler.execute_sql(
+ ^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/db/models/sql/compiler.py", line 1610, in execute_sql
+ sql, params = self.as_sql()
+ ^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/db/models/sql/compiler.py", line 766, in as_sql
+ extra_select, order_by, group_by = self.pre_sql_setup(
+ ^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/db/models/sql/compiler.py", line 85, in pre_sql_setup
+ self.setup_query(with_col_aliases=with_col_aliases)
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/db/models/sql/compiler.py", line 74, in setup_query
+ self.select, self.klass_info, self.annotation_col_map = self.get_select(
+ ^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/db/models/sql/compiler.py", line 299, in get_select
+ related_klass_infos = self.get_related_selections(select, select_mask)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/db/models/sql/compiler.py", line 1265, in get_related_selections
+ next_klass_infos = self.get_related_selections(
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/db/models/sql/compiler.py", line 1396, in get_related_selections
+ raise FieldError(
+django.core.exceptions.FieldError: Invalid field name(s) given in select_related: 'manager'. Choices are: tenant, user, department, supervisor, created_by
+ERROR 2025-09-07 15:37:37,756 basehttp 44551 6164459520 "GET /en/hr/reviews/8/ HTTP/1.1" 500 173140
+WARNING 2025-09-07 15:37:37,772 log 44551 6164459520 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 15:37:37,772 basehttp 44551 6164459520 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-07 15:38:15,889 autoreload 44551 8747049152 /Users/marwanalwali/manus_project/hospital_management_system_v4/hr/views.py changed, reloading.
+INFO 2025-09-07 15:38:16,260 autoreload 47337 8747049152 Watching for file changes with StatReloader
+ERROR 2025-09-07 15:38:16,841 log 47337 6194507776 Internal Server Error: /en/hr/reviews/8/
+Traceback (most recent call last):
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/core/handlers/exception.py", line 55, in inner
+ response = get_response(request)
+ ^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/core/handlers/base.py", line 197, in _get_response
+ response = wrapped_callback(request, *callback_args, **callback_kwargs)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/views/generic/base.py", line 105, in view
+ return self.dispatch(request, *args, **kwargs)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/contrib/auth/mixins.py", line 73, in dispatch
+ return super().dispatch(request, *args, **kwargs)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/views/generic/base.py", line 144, in dispatch
+ return handler(request, *args, **kwargs)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/views/generic/detail.py", line 112, in get
+ self.object = self.get_object()
+ ^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/hr/views.py", line 712, in get_object
+ return get_object_or_404(queryset, pk=self.kwargs.get(self.pk_url_kwarg, self.kwargs.get('pk')))
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/shortcuts.py", line 90, in get_object_or_404
+ return queryset.get(*args, **kwargs)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/db/models/query.py", line 629, in get
+ num = len(clone)
+ ^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/db/models/query.py", line 366, in __len__
+ self._fetch_all()
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/db/models/query.py", line 1949, in _fetch_all
+ self._result_cache = list(self._iterable_class(self))
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/db/models/query.py", line 91, in __iter__
+ results = compiler.execute_sql(
+ ^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/db/models/sql/compiler.py", line 1610, in execute_sql
+ sql, params = self.as_sql()
+ ^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/db/models/sql/compiler.py", line 766, in as_sql
+ extra_select, order_by, group_by = self.pre_sql_setup(
+ ^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/db/models/sql/compiler.py", line 85, in pre_sql_setup
+ self.setup_query(with_col_aliases=with_col_aliases)
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/db/models/sql/compiler.py", line 74, in setup_query
+ self.select, self.klass_info, self.annotation_col_map = self.get_select(
+ ^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/db/models/sql/compiler.py", line 299, in get_select
+ related_klass_infos = self.get_related_selections(select, select_mask)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/db/models/sql/compiler.py", line 1396, in get_related_selections
+ raise FieldError(
+django.core.exceptions.FieldError: Invalid field name(s) given in select_related: 'created_by'. Choices are: employee, reviewer
+ERROR 2025-09-07 15:38:16,843 basehttp 47337 6194507776 "GET /en/hr/reviews/8/ HTTP/1.1" 500 161070
+WARNING 2025-09-07 15:38:16,859 log 47337 6194507776 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 15:38:16,859 basehttp 47337 6194507776 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-07 15:38:38,194 autoreload 47337 8747049152 /Users/marwanalwali/manus_project/hospital_management_system_v4/hr/views.py changed, reloading.
+INFO 2025-09-07 15:38:38,527 autoreload 47502 8747049152 Watching for file changes with StatReloader
+ERROR 2025-09-07 15:38:38,784 log 47502 6138064896 Internal Server Error: /en/hr/reviews/8/
+Traceback (most recent call last):
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/core/handlers/exception.py", line 55, in inner
+ response = get_response(request)
+ ^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/core/handlers/base.py", line 197, in _get_response
+ response = wrapped_callback(request, *callback_args, **callback_kwargs)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/views/generic/base.py", line 105, in view
+ return self.dispatch(request, *args, **kwargs)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/contrib/auth/mixins.py", line 73, in dispatch
+ return super().dispatch(request, *args, **kwargs)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/views/generic/base.py", line 144, in dispatch
+ return handler(request, *args, **kwargs)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/views/generic/detail.py", line 112, in get
+ self.object = self.get_object()
+ ^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/hr/views.py", line 712, in get_object
+ return get_object_or_404(queryset, pk=self.kwargs.get(self.pk_url_kwarg, self.kwargs.get('pk')))
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/shortcuts.py", line 90, in get_object_or_404
+ return queryset.get(*args, **kwargs)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/db/models/query.py", line 629, in get
+ num = len(clone)
+ ^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/db/models/query.py", line 366, in __len__
+ self._fetch_all()
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/db/models/query.py", line 1951, in _fetch_all
+ self._prefetch_related_objects()
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/db/models/query.py", line 1328, in _prefetch_related_objects
+ prefetch_related_objects(self._result_cache, *self._prefetch_related_lookups)
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/db/models/query.py", line 2372, in prefetch_related_objects
+ raise AttributeError(
+AttributeError: Cannot find 'categories' on PerformanceReview object, 'categories' is an invalid parameter to prefetch_related()
+ERROR 2025-09-07 15:38:38,785 basehttp 47502 6138064896 "GET /en/hr/reviews/8/ HTTP/1.1" 500 113875
+WARNING 2025-09-07 15:38:38,798 log 47502 6138064896 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 15:38:38,798 basehttp 47502 6138064896 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-07 15:38:51,266 autoreload 47502 8747049152 /Users/marwanalwali/manus_project/hospital_management_system_v4/hr/views.py changed, reloading.
+INFO 2025-09-07 15:38:51,619 autoreload 47588 8747049152 Watching for file changes with StatReloader
+INFO 2025-09-07 15:39:40,551 autoreload 47588 8747049152 /Users/marwanalwali/manus_project/hospital_management_system_v4/hr/views.py changed, reloading.
+INFO 2025-09-07 15:39:40,898 autoreload 47977 8747049152 Watching for file changes with StatReloader
+ERROR 2025-09-07 15:39:41,445 log 47977 6199848960 Internal Server Error: /en/hr/reviews/8/
+Traceback (most recent call last):
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/core/handlers/exception.py", line 55, in inner
+ response = get_response(request)
+ ^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/core/handlers/base.py", line 197, in _get_response
+ response = wrapped_callback(request, *callback_args, **callback_kwargs)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/views/generic/base.py", line 105, in view
+ return self.dispatch(request, *args, **kwargs)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/contrib/auth/mixins.py", line 73, in dispatch
+ return super().dispatch(request, *args, **kwargs)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/views/generic/base.py", line 144, in dispatch
+ return handler(request, *args, **kwargs)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/views/generic/detail.py", line 112, in get
+ self.object = self.get_object()
+ ^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/hr/views.py", line 712, in get_object
+ return get_object_or_404(queryset, pk=self.kwargs.get(self.pk_url_kwarg, self.kwargs.get('pk')))
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/shortcuts.py", line 90, in get_object_or_404
+ return queryset.get(*args, **kwargs)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/db/models/query.py", line 629, in get
+ num = len(clone)
+ ^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/db/models/query.py", line 366, in __len__
+ self._fetch_all()
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/db/models/query.py", line 1951, in _fetch_all
+ self._prefetch_related_objects()
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/db/models/query.py", line 1328, in _prefetch_related_objects
+ prefetch_related_objects(self._result_cache, *self._prefetch_related_lookups)
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/db/models/query.py", line 2386, in prefetch_related_objects
+ raise ValueError(
+ValueError: 'review_type' does not resolve to an item that supports prefetching - this is an invalid parameter to prefetch_related().
+ERROR 2025-09-07 15:39:41,447 basehttp 47977 6199848960 "GET /en/hr/reviews/8/ HTTP/1.1" 500 113884
+WARNING 2025-09-07 15:39:41,458 log 47977 6199848960 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 15:39:41,458 basehttp 47977 6199848960 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-07 15:40:35,131 autoreload 47977 8747049152 /Users/marwanalwali/manus_project/hospital_management_system_v4/hr/views.py changed, reloading.
+INFO 2025-09-07 15:40:35,503 autoreload 48369 8747049152 Watching for file changes with StatReloader
+ERROR 2025-09-07 15:40:36,071 log 48369 6163918848 Internal Server Error: /en/hr/reviews/8/
+Traceback (most recent call last):
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/core/handlers/exception.py", line 55, in inner
+ response = get_response(request)
+ ^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/core/handlers/base.py", line 197, in _get_response
+ response = wrapped_callback(request, *callback_args, **callback_kwargs)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/views/generic/base.py", line 105, in view
+ return self.dispatch(request, *args, **kwargs)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/contrib/auth/mixins.py", line 73, in dispatch
+ return super().dispatch(request, *args, **kwargs)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/views/generic/base.py", line 144, in dispatch
+ return handler(request, *args, **kwargs)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/views/generic/detail.py", line 112, in get
+ self.object = self.get_object()
+ ^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/hr/views.py", line 712, in get_object
+ return get_object_or_404(queryset, pk=self.kwargs.get(self.pk_url_kwarg, self.kwargs.get('pk')))
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/shortcuts.py", line 90, in get_object_or_404
+ return queryset.get(*args, **kwargs)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/db/models/query.py", line 629, in get
+ num = len(clone)
+ ^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/db/models/query.py", line 366, in __len__
+ self._fetch_all()
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/db/models/query.py", line 1951, in _fetch_all
+ self._prefetch_related_objects()
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/db/models/query.py", line 1328, in _prefetch_related_objects
+ prefetch_related_objects(self._result_cache, *self._prefetch_related_lookups)
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/db/models/query.py", line 2372, in prefetch_related_objects
+ raise AttributeError(
+AttributeError: Cannot find 'goals' on PerformanceReview object, 'goals' is an invalid parameter to prefetch_related()
+ERROR 2025-09-07 15:40:36,072 basehttp 48369 6163918848 "GET /en/hr/reviews/8/ HTTP/1.1" 500 113687
+WARNING 2025-09-07 15:40:36,088 log 48369 6163918848 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 15:40:36,088 basehttp 48369 6163918848 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-07 15:40:44,031 autoreload 48369 8747049152 /Users/marwanalwali/manus_project/hospital_management_system_v4/hr/views.py changed, reloading.
+INFO 2025-09-07 15:40:44,357 autoreload 48481 8747049152 Watching for file changes with StatReloader
+ERROR 2025-09-07 15:40:44,695 log 48481 6130069504 Internal Server Error: /en/hr/reviews/8/
+Traceback (most recent call last):
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/core/handlers/exception.py", line 55, in inner
+ response = get_response(request)
+ ^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/core/handlers/base.py", line 197, in _get_response
+ response = wrapped_callback(request, *callback_args, **callback_kwargs)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/views/generic/base.py", line 105, in view
+ return self.dispatch(request, *args, **kwargs)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/contrib/auth/mixins.py", line 73, in dispatch
+ return super().dispatch(request, *args, **kwargs)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/views/generic/base.py", line 144, in dispatch
+ return handler(request, *args, **kwargs)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/views/generic/detail.py", line 113, in get
+ context = self.get_context_data(object=self.object)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/hr/views.py", line 780, in get_context_data
+ .order_by('-period_end')[:5]
+ ^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/db/models/query.py", line 1722, in order_by
+ obj.query.add_ordering(*field_names)
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/db/models/sql/query.py", line 2291, in add_ordering
+ self.names_to_path(item.split(LOOKUP_SEP), self.model._meta)
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/db/models/sql/query.py", line 1805, in names_to_path
+ raise FieldError(
+django.core.exceptions.FieldError: Cannot resolve keyword 'period_end' into field. Choices are: areas_for_improvement, competency_ratings, created_at, development_plan, employee, employee_comments, employee_id, employee_signature_date, future_goals, goals_achieved, goals_not_achieved, id, notes, overall_rating, review_date, review_id, review_period_end, review_period_start, review_type, reviewer, reviewer_id, status, strengths, training_recommendations, updated_at
+ERROR 2025-09-07 15:40:44,696 basehttp 48481 6130069504 "GET /en/hr/reviews/8/ HTTP/1.1" 500 104264
+WARNING 2025-09-07 15:40:44,707 log 48481 6130069504 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 15:40:44,707 basehttp 48481 6130069504 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-07 15:41:18,911 autoreload 48481 8747049152 /Users/marwanalwali/manus_project/hospital_management_system_v4/hr/views.py changed, reloading.
+INFO 2025-09-07 15:41:19,236 autoreload 48721 8747049152 Watching for file changes with StatReloader
+INFO 2025-09-07 15:41:20,478 basehttp 48721 6122270720 "GET /en/hr/reviews/8/ HTTP/1.1" 200 35458
+WARNING 2025-09-07 15:41:20,492 log 48721 6122270720 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 15:41:20,492 basehttp 48721 6122270720 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-07 15:41:20,493 basehttp 48721 6139097088 "GET /static/plugins/chart.js/dist/chart.umd.js HTTP/1.1" 200 206279
+INFO 2025-09-07 15:41:20,573 basehttp 48721 6122270720 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 15:41:20,574 basehttp 48721 6139097088 "GET /static/plugins/chart.js/dist/chart.umd.js.map HTTP/1.1" 200 958364
+INFO 2025-09-07 15:42:20,568 basehttp 48721 6139097088 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 15:43:20,570 basehttp 48721 6139097088 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 15:44:03,623 autoreload 48721 8747049152 /Users/marwanalwali/manus_project/hospital_management_system_v4/hr/views.py changed, reloading.
+INFO 2025-09-07 15:44:03,983 autoreload 49957 8747049152 Watching for file changes with StatReloader
+INFO 2025-09-07 15:44:20,650 basehttp 49957 6130266112 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 15:44:49,174 basehttp 49957 6130266112 "GET /en/hr/reviews/8/ HTTP/1.1" 200 47214
+WARNING 2025-09-07 15:44:49,195 log 49957 6130266112 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 15:44:49,195 basehttp 49957 6130266112 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-07 15:44:49,262 basehttp 49957 6130266112 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 15:45:49,267 basehttp 49957 6130266112 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+WARNING 2025-09-07 15:46:24,712 log 49957 6130266112 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 15:46:24,712 basehttp 49957 6130266112 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+ERROR 2025-09-07 15:46:29,157 log 49957 6130266112 Internal Server Error: /en/hr/reviews/55/
+Traceback (most recent call last):
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/core/handlers/exception.py", line 55, in inner
+ response = get_response(request)
+ ^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/core/handlers/base.py", line 220, in _get_response
+ response = response.render()
+ ^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/response.py", line 114, in render
+ self.content = self.rendered_content
+ ^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/response.py", line 92, in rendered_content
+ return template.render(context, self._request)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/backends/django.py", line 107, in render
+ return self.template.render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 171, in render
+ return self._render(context)
+ ^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 163, in _render
+ return self.nodelist.render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 1016, in render
+ return SafeString("".join([node.render_annotated(context) for node in self]))
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 977, in render_annotated
+ return self.render(context)
+ ^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/loader_tags.py", line 159, in render
+ return compiled_parent._render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 163, in _render
+ return self.nodelist.render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 1016, in render
+ return SafeString("".join([node.render_annotated(context) for node in self]))
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 977, in render_annotated
+ return self.render(context)
+ ^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/loader_tags.py", line 65, in render
+ result = block.nodelist.render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 1016, in render
+ return SafeString("".join([node.render_annotated(context) for node in self]))
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 977, in render_annotated
+ return self.render(context)
+ ^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/defaulttags.py", line 327, in render
+ return nodelist.render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 1016, in render
+ return SafeString("".join([node.render_annotated(context) for node in self]))
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 977, in render_annotated
+ return self.render(context)
+ ^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/defaulttags.py", line 480, in render
+ url = reverse(view_name, args=args, kwargs=kwargs, current_app=current_app)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/urls/base.py", line 98, in reverse
+ resolved_url = resolver._reverse_with_prefix(view, prefix, *args, **kwargs)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/urls/resolvers.py", line 831, in _reverse_with_prefix
+ raise NoReverseMatch(msg)
+django.urls.exceptions.NoReverseMatch: Reverse for 'complete_performance_review' not found. 'complete_performance_review' is not a valid view function or pattern name.
+ERROR 2025-09-07 15:46:29,159 basehttp 49957 6130266112 "GET /en/hr/reviews/55/ HTTP/1.1" 500 212138
+WARNING 2025-09-07 15:46:29,174 log 49957 6130266112 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 15:46:29,174 basehttp 49957 6130266112 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-07 16:03:50,066 autoreload 49957 8747049152 /Users/marwanalwali/manus_project/hospital_management_system_v4/hr/views.py changed, reloading.
+INFO 2025-09-07 16:03:50,557 autoreload 58605 8747049152 Watching for file changes with StatReloader
+INFO 2025-09-07 16:05:14,742 autoreload 58605 8747049152 /Users/marwanalwali/manus_project/hospital_management_system_v4/hr/urls.py changed, reloading.
+INFO 2025-09-07 16:05:15,058 autoreload 59264 8747049152 Watching for file changes with StatReloader
+INFO 2025-09-07 16:05:15,422 basehttp 59264 6191017984 "GET /en/hr/reviews/55/ HTTP/1.1" 200 47768
+WARNING 2025-09-07 16:05:15,435 log 59264 6191017984 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 16:05:15,435 basehttp 59264 6191017984 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-07 16:05:15,496 basehttp 59264 6191017984 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 16:06:15,511 basehttp 59264 6191017984 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 16:07:15,498 basehttp 59264 6191017984 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 16:07:47,624 basehttp 59264 6191017984 "GET /en/hr/reviews/55/ HTTP/1.1" 200 48316
+WARNING 2025-09-07 16:07:47,639 log 59264 6191017984 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 16:07:47,639 basehttp 59264 6191017984 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-07 16:07:47,693 basehttp 59264 6191017984 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 16:08:32,659 basehttp 59264 6191017984 "GET /en/hr/reviews/55/ HTTP/1.1" 200 48847
+WARNING 2025-09-07 16:08:32,673 log 59264 6191017984 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 16:08:32,674 basehttp 59264 6191017984 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-07 16:08:32,728 basehttp 59264 6191017984 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+WARNING 2025-09-07 16:08:58,962 log 59264 6191017984 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 16:08:58,962 basehttp 59264 6191017984 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-07 16:09:31,141 basehttp 59264 6191017984 "GET /en/hr/reviews/ HTTP/1.1" 200 149783
+INFO 2025-09-07 16:09:31,156 basehttp 59264 6258323456 "GET /static/plugins/datatables.net-bs5/css/dataTables.bootstrap5.min.css HTTP/1.1" 200 15096
+INFO 2025-09-07 16:09:31,157 basehttp 59264 6224670720 "GET /static/css/custom.css HTTP/1.1" 200 2063
+INFO 2025-09-07 16:09:31,157 basehttp 59264 6275149824 "GET /static/plugins/datatables.net-responsive-bs5/css/responsive.bootstrap5.min.css HTTP/1.1" 200 6044
+WARNING 2025-09-07 16:09:31,161 log 59264 6241497088 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+INFO 2025-09-07 16:09:31,161 basehttp 59264 6258323456 "GET /static/plugins/bootstrap-daterangepicker/daterangepicker.css HTTP/1.1" 200 8069
+WARNING 2025-09-07 16:09:31,161 basehttp 59264 6241497088 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-07 16:09:31,163 basehttp 59264 6191017984 "GET /static/css/vendor.min.css HTTP/1.1" 200 177466
+INFO 2025-09-07 16:09:31,164 basehttp 59264 6275149824 "GET /static/img/user/user-4.jpg HTTP/1.1" 200 5916
+INFO 2025-09-07 16:09:31,166 basehttp 59264 6224670720 "GET /static/js/htmx.min.js HTTP/1.1" 200 50917
+INFO 2025-09-07 16:09:31,168 basehttp 59264 6275149824 "GET /static/plugins/datatables.net-bs5/js/dataTables.bootstrap5.min.js HTTP/1.1" 200 1470
+INFO 2025-09-07 16:09:31,170 basehttp 59264 6207844352 "GET /static/css/default/app.min.css HTTP/1.1" 200 893480
+INFO 2025-09-07 16:09:31,171 basehttp 59264 6275149824 "GET /static/plugins/datatables.net-responsive-bs5/js/responsive.bootstrap5.min.js HTTP/1.1" 200 1796
+INFO 2025-09-07 16:09:31,172 basehttp 59264 6258323456 "GET /static/js/app.min.js HTTP/1.1" 200 110394
+INFO 2025-09-07 16:09:31,173 basehttp 59264 6191017984 "GET /static/plugins/datatables.net/js/dataTables.min.js HTTP/1.1" 200 95735
+INFO 2025-09-07 16:09:31,175 basehttp 59264 6224670720 "GET /static/plugins/datatables.net-responsive/js/dataTables.responsive.min.js HTTP/1.1" 200 16086
+INFO 2025-09-07 16:09:31,181 basehttp 59264 6241497088 "GET /static/js/vendor.min.js HTTP/1.1" 200 1091361
+INFO 2025-09-07 16:09:31,184 basehttp 59264 6275149824 "GET /static/plugins/bootstrap-daterangepicker/daterangepicker.js HTTP/1.1" 200 67842
+INFO 2025-09-07 16:09:31,186 basehttp 59264 6258323456 "GET /static/plugins/select2/dist/js/select2.min.js HTTP/1.1" 200 70851
+INFO 2025-09-07 16:09:31,188 basehttp 59264 6207844352 "GET /static/plugins/moment/min/moment.min.js HTTP/1.1" 200 58890
+INFO 2025-09-07 16:09:32,003 basehttp 59264 6207844352 "GET /static/img/theme/default.jpg HTTP/1.1" 200 26964
+INFO 2025-09-07 16:09:32,003 basehttp 59264 6241497088 "GET /static/img/theme/material.jpg HTTP/1.1" 200 28774
+INFO 2025-09-07 16:09:32,003 basehttp 59264 6224670720 "GET /static/img/theme/facebook.jpg HTTP/1.1" 200 27881
+INFO 2025-09-07 16:09:32,003 basehttp 59264 6258323456 "GET /static/img/theme/transparent.jpg HTTP/1.1" 200 32747
+INFO 2025-09-07 16:09:32,004 basehttp 59264 6275149824 "GET /static/img/theme/apple.jpg HTTP/1.1" 200 28822
+INFO 2025-09-07 16:09:32,006 basehttp 59264 6191017984 "GET /static/img/theme/google.jpg HTTP/1.1" 200 86013
+INFO 2025-09-07 16:09:32,008 basehttp 59264 6241497088 "GET /static/img/version/html.jpg HTTP/1.1" 200 17325
+INFO 2025-09-07 16:09:32,008 basehttp 59264 6258323456 "GET /static/img/version/ajax.jpg HTTP/1.1" 200 20223
+INFO 2025-09-07 16:09:32,010 basehttp 59264 6191017984 "GET /static/img/version/svelte.jpg HTTP/1.1" 200 25060
+INFO 2025-09-07 16:09:32,010 basehttp 59264 6224670720 "GET /static/img/version/angular1x.jpg HTTP/1.1" 200 22869
+INFO 2025-09-07 16:09:32,010 basehttp 59264 6275149824 "GET /static/img/version/angular10x.jpg HTTP/1.1" 200 24580
+INFO 2025-09-07 16:09:32,011 basehttp 59264 6241497088 "GET /static/img/version/django.jpg HTTP/1.1" 200 20935
+INFO 2025-09-07 16:09:32,013 basehttp 59264 6191017984 "GET /static/img/version/dotnet.jpg HTTP/1.1" 200 24791
+INFO 2025-09-07 16:09:32,013 basehttp 59264 6258323456 "GET /static/img/version/laravel.jpg HTTP/1.1" 200 26040
+INFO 2025-09-07 16:09:32,013 basehttp 59264 6224670720 "GET /static/img/version/reactjs.jpg HTTP/1.1" 200 26850
+INFO 2025-09-07 16:09:32,013 basehttp 59264 6275149824 "GET /static/img/version/vuejs.jpg HTTP/1.1" 200 22518
+INFO 2025-09-07 16:09:32,015 basehttp 59264 6207844352 "GET /static/webfonts/fa-solid-900.woff2 HTTP/1.1" 200 158220
+INFO 2025-09-07 16:09:32,016 basehttp 59264 6275149824 "GET /static/img/theme/blog.jpg HTTP/1.1" 200 32334
+INFO 2025-09-07 16:09:32,016 basehttp 59264 6241497088 "GET /static/img/version/nextjs.jpg HTTP/1.1" 200 20152
+INFO 2025-09-07 16:09:32,017 basehttp 59264 6224670720 "GET /static/img/theme/e-commerce.jpg HTTP/1.1" 200 37734
+INFO 2025-09-07 16:09:32,017 basehttp 59264 6191017984 "GET /static/img/theme/forum.jpg HTTP/1.1" 200 28744
+INFO 2025-09-07 16:09:32,017 basehttp 59264 6207844352 "GET /static/img/theme/corporate.jpg HTTP/1.1" 200 38911
+INFO 2025-09-07 16:09:32,017 basehttp 59264 6258323456 "GET /static/img/theme/one-page-parallax.jpg HTTP/1.1" 200 22474
+INFO 2025-09-07 16:09:32,030 basehttp 59264 6191017984 "GET /static/css/default/app.min.css.map HTTP/1.1" 200 1957526
+INFO 2025-09-07 16:09:32,034 basehttp 59264 6207844352 "GET /static/plugins/moment/min/moment.min.js.map HTTP/1.1" 200 98730
+INFO 2025-09-07 16:09:32,046 basehttp 59264 6207844352 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+WARNING 2025-09-07 16:09:32,133 log 59264 6207844352 Not Found: /favicon.ico
+WARNING 2025-09-07 16:09:32,133 basehttp 59264 6207844352 "GET /favicon.ico HTTP/1.1" 404 2557
+INFO 2025-09-07 16:09:44,724 basehttp 59264 6207844352 "GET /en/hr/reviews/29/ HTTP/1.1" 200 54428
+INFO 2025-09-07 16:09:44,741 basehttp 59264 6191017984 "GET /static/plugins/chart.js/dist/chart.umd.js HTTP/1.1" 200 206279
+WARNING 2025-09-07 16:09:44,745 log 59264 6207844352 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 16:09:44,745 basehttp 59264 6207844352 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-07 16:09:44,805 basehttp 59264 6207844352 "GET /static/webfonts/fa-regular-400.woff2 HTTP/1.1" 200 25472
+INFO 2025-09-07 16:09:44,820 basehttp 59264 6207844352 "GET /static/plugins/chart.js/dist/chart.umd.js.map HTTP/1.1" 200 958364
+INFO 2025-09-07 16:09:44,827 basehttp 59264 6207844352 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+WARNING 2025-09-07 16:10:14,116 log 59264 6207844352 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 16:10:14,116 basehttp 59264 6207844352 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+WARNING 2025-09-07 16:10:14,126 log 59264 6207844352 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 16:10:14,126 basehttp 59264 6207844352 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-07 16:10:17,915 basehttp 59264 6207844352 "GET /en/hr/reviews/55/ HTTP/1.1" 200 48847
+WARNING 2025-09-07 16:10:17,932 log 59264 6207844352 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 16:10:17,932 basehttp 59264 6207844352 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-07 16:10:18,030 basehttp 59264 6207844352 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 16:10:22,113 basehttp 59264 6207844352 "GET /en/hr/reviews/55/complete/ HTTP/1.1" 302 0
+INFO 2025-09-07 16:10:22,127 basehttp 59264 6207844352 "GET /en/hr/reviews/55/ HTTP/1.1" 200 48707
+WARNING 2025-09-07 16:10:22,143 log 59264 6207844352 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 16:10:22,144 basehttp 59264 6207844352 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-07 16:10:22,191 basehttp 59264 6207844352 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 16:10:39,472 basehttp 59264 6207844352 "GET /en/hr/reviews/ HTTP/1.1" 200 148767
+WARNING 2025-09-07 16:10:39,493 log 59264 6207844352 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 16:10:39,493 basehttp 59264 6207844352 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-07 16:10:39,562 basehttp 59264 6207844352 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 16:10:45,577 basehttp 59264 6207844352 "GET /en/hr/reviews/86/ HTTP/1.1" 200 54386
+WARNING 2025-09-07 16:10:45,601 log 59264 6207844352 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 16:10:45,601 basehttp 59264 6207844352 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-07 16:10:45,648 basehttp 59264 6207844352 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 16:11:06,099 basehttp 59264 6207844352 "GET /en/hr/reviews/87/ HTTP/1.1" 200 46425
+WARNING 2025-09-07 16:11:06,121 log 59264 6207844352 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 16:11:06,121 basehttp 59264 6207844352 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-07 16:11:06,171 basehttp 59264 6207844352 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 16:11:12,234 basehttp 59264 6207844352 "GET /en/hr/reviews/86/ HTTP/1.1" 200 54386
+WARNING 2025-09-07 16:11:12,258 log 59264 6207844352 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 16:11:12,258 basehttp 59264 6207844352 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-07 16:11:12,312 basehttp 59264 6207844352 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+WARNING 2025-09-07 16:11:20,964 log 59264 6207844352 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 16:11:20,964 basehttp 59264 6207844352 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+WARNING 2025-09-07 16:11:20,977 log 59264 6207844352 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 16:11:20,977 basehttp 59264 6207844352 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-07 16:11:22,229 basehttp 59264 6207844352 "GET / HTTP/1.1" 302 0
+INFO 2025-09-07 16:11:22,252 basehttp 59264 6191017984 "GET /en/ HTTP/1.1" 200 49810
+WARNING 2025-09-07 16:11:22,273 log 59264 6191017984 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 16:11:22,273 basehttp 59264 6191017984 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-07 16:11:22,342 basehttp 59264 6191017984 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 16:11:22,346 basehttp 59264 6224670720 "GET /en/htmx/tenant-info/ HTTP/1.1" 200 1043
+INFO 2025-09-07 16:11:22,348 basehttp 59264 6275149824 "GET /en/htmx/system-health/ HTTP/1.1" 200 1356
+INFO 2025-09-07 16:11:22,350 basehttp 59264 6258323456 "GET /en/htmx/dashboard-stats/ HTTP/1.1" 200 2094
+INFO 2025-09-07 16:11:25,239 basehttp 59264 6258323456 "GET /en/hr HTTP/1.1" 301 0
+INFO 2025-09-07 16:11:25,273 basehttp 59264 6275149824 "GET /en/hr/ HTTP/1.1" 200 42394
+WARNING 2025-09-07 16:11:25,294 log 59264 6275149824 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 16:11:25,294 basehttp 59264 6275149824 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-07 16:11:25,309 basehttp 59264 6275149824 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 16:11:33,103 basehttp 59264 6275149824 "GET /en/hr/departments/ HTTP/1.1" 200 125426
+INFO 2025-09-07 16:11:33,121 basehttp 59264 6275149824 "GET /static/plugins/datatables.net-buttons-bs5/css/buttons.bootstrap5.min.css HTTP/1.1" 200 8136
+INFO 2025-09-07 16:11:33,121 basehttp 59264 6241497088 "GET /static/plugins/datatables.net-buttons-bs5/js/buttons.bootstrap5.min.js HTTP/1.1" 200 1627
+INFO 2025-09-07 16:11:33,121 basehttp 59264 6224670720 "GET /static/plugins/select2/dist/css/select2.min.css HTTP/1.1" 200 14966
+INFO 2025-09-07 16:11:33,122 basehttp 59264 6191017984 "GET /static/plugins/datatables.net-buttons/js/dataTables.buttons.min.js HTTP/1.1" 200 27926
+WARNING 2025-09-07 16:11:33,126 log 59264 6207844352 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 16:11:33,127 basehttp 59264 6207844352 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-07 16:11:33,128 basehttp 59264 6224670720 "GET /static/plugins/datatables.net-buttons/js/buttons.print.min.js HTTP/1.1" 200 3073
+INFO 2025-09-07 16:11:33,131 basehttp 59264 6241497088 "GET /static/plugins/jszip/dist/jszip.min.js HTTP/1.1" 200 97630
+INFO 2025-09-07 16:11:33,131 basehttp 59264 6191017984 "GET /static/plugins/datatables.net-buttons/js/buttons.html5.min.js HTTP/1.1" 200 26043
+INFO 2025-09-07 16:11:33,138 basehttp 59264 6258323456 "GET /static/plugins/pdfmake/build/vfs_fonts.js HTTP/1.1" 200 828866
+INFO 2025-09-07 16:11:33,144 basehttp 59264 6275149824 "GET /static/plugins/pdfmake/build/pdfmake.min.js HTTP/1.1" 200 1400771
+INFO 2025-09-07 16:11:33,217 basehttp 59264 6258323456 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 16:11:33,228 basehttp 59264 6275149824 "GET /static/plugins/pdfmake/build/pdfmake.min.js.map HTTP/1.1" 200 4214503
+INFO 2025-09-07 16:12:34,200 basehttp 59264 6275149824 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 16:13:12,441 basehttp 59264 6275149824 "GET /en/hr/departments/12/delete/ HTTP/1.1" 200 30311
+WARNING 2025-09-07 16:13:12,464 log 59264 6275149824 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 16:13:12,464 basehttp 59264 6275149824 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-07 16:13:12,504 basehttp 59264 6275149824 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 16:13:21,744 basehttp 59264 6275149824 "GET /en/hr/departments/12/ HTTP/1.1" 200 35129
+WARNING 2025-09-07 16:13:21,762 basehttp 59264 6258323456 "GET /static/plugins/chart.js/dist/Chart.min.css HTTP/1.1" 404 2032
+WARNING 2025-09-07 16:13:21,765 basehttp 59264 6241497088 "GET /static/plugins/chart.js/dist/Chart.min.js HTTP/1.1" 404 2029
+WARNING 2025-09-07 16:13:21,767 basehttp 59264 6191017984 "GET /static/plugins/datatables.net/js/jquery.dataTables.min.js HTTP/1.1" 404 2077
+WARNING 2025-09-07 16:13:21,769 log 59264 6275149824 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 16:13:21,769 basehttp 59264 6275149824 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-07 16:13:21,800 basehttp 59264 6275149824 "GET /static/css/saudiriyalsymbol.woff2 HTTP/1.1" 200 720
+INFO 2025-09-07 16:13:21,812 basehttp 59264 6275149824 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 16:13:36,120 basehttp 59264 6275149824 "GET /en/hr/departments/12/update/ HTTP/1.1" 200 41458
+WARNING 2025-09-07 16:13:36,137 basehttp 59264 6275149824 "GET /static/plugins/select2-bootstrap5-theme/select2-bootstrap5.min.css HTTP/1.1" 404 2104
+WARNING 2025-09-07 16:13:36,143 log 59264 6224670720 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 16:13:36,143 basehttp 59264 6224670720 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-07 16:13:36,192 basehttp 59264 6224670720 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 16:13:51,429 basehttp 59264 6224670720 "GET /en/hr/departments/ HTTP/1.1" 200 125426
+WARNING 2025-09-07 16:13:51,446 log 59264 6224670720 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 16:13:51,446 basehttp 59264 6224670720 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-07 16:13:51,546 basehttp 59264 6224670720 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 16:14:15,846 basehttp 59264 6224670720 "GET /en/hr/departments/10/ HTTP/1.1" 200 52158
+WARNING 2025-09-07 16:14:15,863 basehttp 59264 6224670720 "GET /static/plugins/chart.js/dist/Chart.min.css HTTP/1.1" 404 2032
+WARNING 2025-09-07 16:14:15,867 basehttp 59264 6207844352 "GET /static/plugins/datatables.net/js/jquery.dataTables.min.js HTTP/1.1" 404 2077
+WARNING 2025-09-07 16:14:15,867 basehttp 59264 6191017984 "GET /static/plugins/chart.js/dist/Chart.min.js HTTP/1.1" 404 2029
+WARNING 2025-09-07 16:14:15,870 log 59264 6241497088 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 16:14:15,870 basehttp 59264 6241497088 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-07 16:14:15,914 basehttp 59264 6241497088 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 16:14:51,664 basehttp 59264 6241497088 "GET /en/hr/employees/52/ HTTP/1.1" 200 34483
+WARNING 2025-09-07 16:14:51,686 log 59264 6241497088 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 16:14:51,687 basehttp 59264 6241497088 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-07 16:14:51,729 basehttp 59264 6241497088 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 16:15:51,745 basehttp 59264 6191017984 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 16:16:51,736 basehttp 59264 6191017984 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 16:17:51,739 basehttp 59264 6191017984 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 16:18:25,132 basehttp 59264 6191017984 "GET /en/hr/employees/52/ HTTP/1.1" 200 36484
+WARNING 2025-09-07 16:18:25,143 log 59264 6191017984 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 16:18:25,143 basehttp 59264 6191017984 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-07 16:18:25,186 basehttp 59264 6191017984 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 16:18:48,463 basehttp 59264 6191017984 "GET /en/hr/employees/52/ HTTP/1.1" 200 36493
+WARNING 2025-09-07 16:18:48,479 log 59264 6191017984 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 16:18:48,479 basehttp 59264 6191017984 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-07 16:18:48,517 basehttp 59264 6191017984 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 16:19:48,522 basehttp 59264 6191017984 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 16:20:48,535 basehttp 59264 6191017984 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 16:21:16,667 basehttp 59264 6191017984 "GET /en/hr/employees/52/ HTTP/1.1" 200 35212
+WARNING 2025-09-07 16:21:16,680 log 59264 6191017984 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 16:21:16,681 basehttp 59264 6191017984 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-07 16:21:16,729 basehttp 59264 6191017984 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 16:22:16,739 basehttp 59264 6191017984 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 16:22:49,183 basehttp 59264 6191017984 "GET /en/hr/employees/52/ HTTP/1.1" 200 35242
+WARNING 2025-09-07 16:22:49,197 log 59264 6191017984 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 16:22:49,197 basehttp 59264 6191017984 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-07 16:22:49,222 basehttp 59264 6191017984 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 16:23:01,175 basehttp 59264 6191017984 "GET /en/hr/employees/52/ HTTP/1.1" 200 35248
+WARNING 2025-09-07 16:23:01,190 log 59264 6191017984 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 16:23:01,191 basehttp 59264 6191017984 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-07 16:23:01,252 basehttp 59264 6191017984 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 16:23:57,143 basehttp 59264 6191017984 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+WARNING 2025-09-07 16:23:57,146 log 59264 6207844352 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 16:23:57,146 basehttp 59264 6207844352 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+WARNING 2025-09-07 16:23:57,149 basehttp 59264 6191017984 "GET /static/plugins/chart.js/dist/Chart.min.css HTTP/1.1" 404 2032
+WARNING 2025-09-07 16:23:57,164 log 59264 6207844352 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 16:23:57,164 basehttp 59264 6207844352 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-07 16:24:57,138 basehttp 59264 6207844352 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 16:25:57,152 basehttp 59264 6207844352 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 16:26:44,382 basehttp 59264 6207844352 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+WARNING 2025-09-07 16:26:44,387 log 59264 6191017984 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 16:26:44,387 basehttp 59264 6191017984 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+WARNING 2025-09-07 16:26:44,400 log 59264 6191017984 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 16:26:44,400 basehttp 59264 6191017984 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+WARNING 2025-09-07 16:26:45,380 log 59264 6191017984 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 16:26:45,380 basehttp 59264 6191017984 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+WARNING 2025-09-07 16:26:45,391 log 59264 6191017984 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 16:26:45,392 basehttp 59264 6191017984 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-07 16:26:46,047 basehttp 59264 6191017984 "GET /en/hr/departments/10/ HTTP/1.1" 200 52071
+INFO 2025-09-07 16:26:46,058 basehttp 59264 6191017984 "GET /static/plugins/chart.js/dist/chart.js HTTP/1.1" 200 403805
+WARNING 2025-09-07 16:26:46,066 log 59264 6191017984 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 16:26:46,066 basehttp 59264 6191017984 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-07 16:26:46,117 basehttp 59264 6191017984 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 16:27:46,133 basehttp 59264 6191017984 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 16:28:15,821 basehttp 59264 6191017984 "GET /en/hr/departments/10/ HTTP/1.1" 200 53084
+WARNING 2025-09-07 16:28:15,836 log 59264 6191017984 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 16:28:15,836 basehttp 59264 6191017984 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-07 16:28:15,892 basehttp 59264 6191017984 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 16:28:27,430 basehttp 59264 6191017984 "GET /en/hr/departments/10/ HTTP/1.1" 200 53084
+WARNING 2025-09-07 16:28:27,449 log 59264 6191017984 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 16:28:27,449 basehttp 59264 6191017984 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-07 16:28:27,510 basehttp 59264 6191017984 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 16:28:37,552 basehttp 59264 6191017984 "GET /en/hr/departments/10/ HTTP/1.1" 200 53084
+WARNING 2025-09-07 16:28:37,569 log 59264 6191017984 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 16:28:37,569 basehttp 59264 6191017984 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-07 16:28:37,614 basehttp 59264 6191017984 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 16:29:20,934 basehttp 59264 6191017984 "GET /en/hr/departments/10/ HTTP/1.1" 200 52404
+WARNING 2025-09-07 16:29:20,949 log 59264 6191017984 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 16:29:20,950 basehttp 59264 6191017984 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-07 16:29:21,002 basehttp 59264 6191017984 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 16:29:28,213 basehttp 59264 6191017984 "GET /en/hr/departments/10/ HTTP/1.1" 200 52071
+WARNING 2025-09-07 16:29:28,231 log 59264 6191017984 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 16:29:28,231 basehttp 59264 6191017984 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-07 16:29:28,283 basehttp 59264 6191017984 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 16:29:48,811 basehttp 59264 6191017984 "GET /en/admin/hr/employee/ HTTP/1.1" 200 158543
+INFO 2025-09-07 16:29:48,826 basehttp 59264 6224670720 "GET /static/admin/css/nav_sidebar.css HTTP/1.1" 200 2810
+INFO 2025-09-07 16:29:48,826 basehttp 59264 6207844352 "GET /static/admin/css/dark_mode.css HTTP/1.1" 200 2808
+INFO 2025-09-07 16:29:48,827 basehttp 59264 6191017984 "GET /static/admin/css/base.css HTTP/1.1" 200 22120
+INFO 2025-09-07 16:29:48,827 basehttp 59264 6241497088 "GET /static/admin/css/changelists.css HTTP/1.1" 200 6878
+INFO 2025-09-07 16:29:48,827 basehttp 59264 6258323456 "GET /static/admin/js/theme.js HTTP/1.1" 200 1653
+INFO 2025-09-07 16:29:48,828 basehttp 59264 6207844352 "GET /static/admin/css/responsive.css HTTP/1.1" 200 16565
+INFO 2025-09-07 16:29:48,828 basehttp 59264 6241497088 "GET /static/admin/js/core.js HTTP/1.1" 200 6208
+INFO 2025-09-07 16:29:48,828 basehttp 59264 6191017984 "GET /static/admin/js/jquery.init.js HTTP/1.1" 200 347
+INFO 2025-09-07 16:29:48,830 basehttp 59264 6258323456 "GET /static/admin/js/admin/RelatedObjectLookups.js HTTP/1.1" 200 9777
+INFO 2025-09-07 16:29:48,830 basehttp 59264 6241497088 "GET /static/admin/js/prepopulate.js HTTP/1.1" 200 1531
+INFO 2025-09-07 16:29:48,831 basehttp 59264 6207844352 "GET /static/admin/js/actions.js HTTP/1.1" 200 8076
+INFO 2025-09-07 16:29:48,832 basehttp 59264 6191017984 "GET /static/admin/js/urlify.js HTTP/1.1" 200 7887
+INFO 2025-09-07 16:29:48,833 basehttp 59264 6241497088 "GET /static/admin/img/search.svg HTTP/1.1" 200 458
+INFO 2025-09-07 16:29:48,835 basehttp 59264 6275149824 "GET /en/admin/jsi18n/ HTTP/1.1" 200 3342
+INFO 2025-09-07 16:29:48,835 basehttp 59264 6224670720 "GET /static/admin/js/vendor/jquery/jquery.js HTTP/1.1" 200 285314
+INFO 2025-09-07 16:29:48,839 basehttp 59264 6224670720 "GET /static/admin/js/nav_sidebar.js HTTP/1.1" 200 3063
+INFO 2025-09-07 16:29:48,839 basehttp 59264 6258323456 "GET /static/admin/js/vendor/xregexp/xregexp.js HTTP/1.1" 200 325171
+INFO 2025-09-07 16:29:48,840 basehttp 59264 6258323456 "GET /static/admin/js/filters.js HTTP/1.1" 200 978
+INFO 2025-09-07 16:29:48,848 basehttp 59264 6258323456 "GET /static/admin/img/icon-addlink.svg HTTP/1.1" 200 331
+INFO 2025-09-07 16:29:48,848 basehttp 59264 6224670720 "GET /static/admin/img/tooltag-add.svg HTTP/1.1" 200 331
+INFO 2025-09-07 16:29:48,849 basehttp 59264 6224670720 "GET /static/admin/img/icon-viewlink.svg HTTP/1.1" 200 581
+INFO 2025-09-07 16:29:56,778 basehttp 59264 6224670720 "GET /en/admin/hr/employee/56/change/ HTTP/1.1" 200 156606
+INFO 2025-09-07 16:29:56,788 basehttp 59264 6224670720 "GET /static/admin/css/forms.css HTTP/1.1" 200 8525
+INFO 2025-09-07 16:29:56,790 basehttp 59264 6191017984 "GET /static/admin/js/prepopulate_init.js HTTP/1.1" 200 586
+INFO 2025-09-07 16:29:56,791 basehttp 59264 6207844352 "GET /static/admin/css/widgets.css HTTP/1.1" 200 11991
+INFO 2025-09-07 16:29:56,791 basehttp 59264 6241497088 "GET /static/admin/js/inlines.js HTTP/1.1" 200 15628
+INFO 2025-09-07 16:29:56,791 basehttp 59264 6258323456 "GET /static/admin/js/calendar.js HTTP/1.1" 200 9141
+INFO 2025-09-07 16:29:56,791 basehttp 59264 6275149824 "GET /static/admin/js/admin/DateTimeShortcuts.js HTTP/1.1" 200 19319
+INFO 2025-09-07 16:29:56,793 basehttp 59264 6275149824 "GET /static/admin/img/icon-changelink.svg HTTP/1.1" 200 380
+INFO 2025-09-07 16:29:56,794 basehttp 59264 6224670720 "GET /en/admin/jsi18n/ HTTP/1.1" 200 3342
+INFO 2025-09-07 16:29:56,794 basehttp 59264 6275149824 "GET /static/admin/img/icon-deletelink.svg HTTP/1.1" 200 392
+INFO 2025-09-07 16:29:56,795 basehttp 59264 6275149824 "GET /static/admin/img/icon-unknown.svg HTTP/1.1" 200 655
+INFO 2025-09-07 16:29:56,795 basehttp 59264 6224670720 "GET /static/admin/js/change_form.js HTTP/1.1" 200 606
+INFO 2025-09-07 16:29:56,826 basehttp 59264 6224670720 "GET /static/admin/img/icon-calendar.svg HTTP/1.1" 200 1086
+INFO 2025-09-07 16:29:57,267 basehttp 59264 6224670720 "GET /en/admin/hr/employee/ HTTP/1.1" 200 158543
+INFO 2025-09-07 16:29:58,269 basehttp 59264 6224670720 "GET /en/admin/hr/employee/56/change/ HTTP/1.1" 200 156606
+INFO 2025-09-07 16:29:58,284 basehttp 59264 6224670720 "GET /en/admin/jsi18n/ HTTP/1.1" 200 3342
+INFO 2025-09-07 16:30:29,184 basehttp 59264 6224670720 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 16:31:06,779 basehttp 59264 6224670720 "GET /en/admin/hr/employee/ HTTP/1.1" 200 158543
+INFO 2025-09-07 16:31:08,868 basehttp 59264 6224670720 "GET /en/admin/hr/employee/25/change/ HTTP/1.1" 200 288687
+INFO 2025-09-07 16:31:08,887 basehttp 59264 6224670720 "GET /en/admin/jsi18n/ HTTP/1.1" 200 3342
+INFO 2025-09-07 16:31:08,932 basehttp 59264 6224670720 "GET /static/admin/img/icon-clock.svg HTTP/1.1" 200 677
+INFO 2025-09-07 16:31:30,175 basehttp 59264 6224670720 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 16:31:32,318 basehttp 59264 6224670720 "GET /en/admin/hr/employee/ HTTP/1.1" 200 158543
+INFO 2025-09-07 16:32:31,121 basehttp 59264 6224670720 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 16:33:32,123 basehttp 59264 6224670720 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 16:34:08,088 autoreload 59264 8747049152 /Users/marwanalwali/manus_project/hospital_management_system_v4/hr/views.py changed, reloading.
+INFO 2025-09-07 16:34:08,524 autoreload 71999 8747049152 Watching for file changes with StatReloader
+WARNING 2025-09-07 16:34:10,955 log 71999 6157496320 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 16:34:10,955 basehttp 71999 6157496320 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+WARNING 2025-09-07 16:34:11,988 log 71999 6157496320 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 16:34:11,989 basehttp 71999 6157496320 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+WARNING 2025-09-07 16:34:12,973 log 71999 6157496320 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 16:34:12,973 basehttp 71999 6157496320 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+WARNING 2025-09-07 16:34:13,585 log 71999 6157496320 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 16:34:13,585 basehttp 71999 6157496320 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+WARNING 2025-09-07 16:34:14,036 log 71999 6157496320 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 16:34:14,036 basehttp 71999 6157496320 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+WARNING 2025-09-07 16:34:14,547 log 71999 6157496320 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 16:34:14,547 basehttp 71999 6157496320 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-07 16:34:40,331 basehttp 71999 6157496320 "GET /en/hr/training/ HTTP/1.1" 200 117094
+WARNING 2025-09-07 16:34:40,352 basehttp 71999 6174322688 "GET /static/plugins/datatables.net/js/jquery.dataTables.min.js HTTP/1.1" 404 2077
+WARNING 2025-09-07 16:34:40,354 log 71999 6157496320 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 16:34:40,354 basehttp 71999 6157496320 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-07 16:34:40,424 basehttp 71999 6157496320 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 16:35:24,917 basehttp 71999 6157496320 "GET /en/hr/training/ HTTP/1.1" 200 117087
+WARNING 2025-09-07 16:35:24,942 log 71999 6157496320 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 16:35:24,942 basehttp 71999 6157496320 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-07 16:35:24,993 basehttp 71999 6157496320 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+ERROR 2025-09-07 16:35:36,374 log 71999 6157496320 Internal Server Error: /en/hr/training/142/
+Traceback (most recent call last):
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/core/handlers/exception.py", line 55, in inner
+ response = get_response(request)
+ ^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/core/handlers/base.py", line 220, in _get_response
+ response = response.render()
+ ^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/response.py", line 114, in render
+ self.content = self.rendered_content
+ ^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/response.py", line 90, in rendered_content
+ template = self.resolve_template(self.template_name)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/response.py", line 72, in resolve_template
+ return select_template(template, using=self.using)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/loader.py", line 42, in select_template
+ return engine.get_template(template_name)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/backends/django.py", line 79, in get_template
+ return Template(self.engine.get_template(template_name), self)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/engine.py", line 177, in get_template
+ template, origin = self.find_template(template_name)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/engine.py", line 159, in find_template
+ template = loader.get_template(name, skip=skip)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/loaders/cached.py", line 57, in get_template
+ template = super().get_template(template_name, skip)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/loaders/base.py", line 28, in get_template
+ return Template(
+ ^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 154, in __init__
+ self.nodelist = self.compile_nodelist()
+ ^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 196, in compile_nodelist
+ nodelist = parser.parse()
+ ^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 518, in parse
+ raise self.error(token, e)
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 516, in parse
+ compiled_result = compile_func(self, token)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/loader_tags.py", line 299, in do_extends
+ nodelist = parser.parse()
+ ^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 518, in parse
+ raise self.error(token, e)
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 516, in parse
+ compiled_result = compile_func(self, token)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/loader_tags.py", line 234, in do_block
+ nodelist = parser.parse(("endblock",))
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 518, in parse
+ raise self.error(token, e)
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 516, in parse
+ compiled_result = compile_func(self, token)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/defaulttags.py", line 962, in do_if
+ nodelist = parser.parse(("elif", "else", "endif"))
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 518, in parse
+ raise self.error(token, e)
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 516, in parse
+ compiled_result = compile_func(self, token)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/defaulttags.py", line 962, in do_if
+ nodelist = parser.parse(("elif", "else", "endif"))
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 518, in parse
+ raise self.error(token, e)
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 516, in parse
+ compiled_result = compile_func(self, token)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/defaulttags.py", line 862, in do_for
+ nodelist_loop = parser.parse(
+ ^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 489, in parse
+ raise self.error(token, e)
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 487, in parse
+ filter_expression = self.compile_filter(token.contents)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 609, in compile_filter
+ return FilterExpression(token, self)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 705, in __init__
+ filter_func = parser.find_filter(filter_name)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 615, in find_filter
+ raise TemplateSyntaxError("Invalid filter: '%s'" % filter_name)
+django.template.exceptions.TemplateSyntaxError: Invalid filter: 'split'
+ERROR 2025-09-07 16:35:36,376 basehttp 71999 6157496320 "GET /en/hr/training/142/ HTTP/1.1" 500 375709
+WARNING 2025-09-07 16:35:36,395 log 71999 6157496320 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 16:35:36,395 basehttp 71999 6157496320 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-07 16:36:29,062 autoreload 71999 8747049152 /Users/marwanalwali/manus_project/hospital_management_system_v4/hr/views.py changed, reloading.
+INFO 2025-09-07 16:36:29,463 autoreload 73004 8747049152 Watching for file changes with StatReloader
+ERROR 2025-09-07 16:36:29,881 log 73004 6191345664 Internal Server Error: /en/hr/training/142/
+Traceback (most recent call last):
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/core/handlers/exception.py", line 55, in inner
+ response = get_response(request)
+ ^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/core/handlers/base.py", line 220, in _get_response
+ response = response.render()
+ ^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/response.py", line 114, in render
+ self.content = self.rendered_content
+ ^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/response.py", line 90, in rendered_content
+ template = self.resolve_template(self.template_name)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/response.py", line 72, in resolve_template
+ return select_template(template, using=self.using)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/loader.py", line 42, in select_template
+ return engine.get_template(template_name)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/backends/django.py", line 79, in get_template
+ return Template(self.engine.get_template(template_name), self)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/engine.py", line 177, in get_template
+ template, origin = self.find_template(template_name)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/engine.py", line 159, in find_template
+ template = loader.get_template(name, skip=skip)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/loaders/cached.py", line 57, in get_template
+ template = super().get_template(template_name, skip)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/loaders/base.py", line 28, in get_template
+ return Template(
+ ^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 154, in __init__
+ self.nodelist = self.compile_nodelist()
+ ^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 196, in compile_nodelist
+ nodelist = parser.parse()
+ ^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 518, in parse
+ raise self.error(token, e)
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 516, in parse
+ compiled_result = compile_func(self, token)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/loader_tags.py", line 299, in do_extends
+ nodelist = parser.parse()
+ ^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 518, in parse
+ raise self.error(token, e)
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 516, in parse
+ compiled_result = compile_func(self, token)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/loader_tags.py", line 234, in do_block
+ nodelist = parser.parse(("endblock",))
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 518, in parse
+ raise self.error(token, e)
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 516, in parse
+ compiled_result = compile_func(self, token)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/defaulttags.py", line 962, in do_if
+ nodelist = parser.parse(("elif", "else", "endif"))
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 518, in parse
+ raise self.error(token, e)
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 516, in parse
+ compiled_result = compile_func(self, token)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/defaulttags.py", line 962, in do_if
+ nodelist = parser.parse(("elif", "else", "endif"))
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 518, in parse
+ raise self.error(token, e)
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 516, in parse
+ compiled_result = compile_func(self, token)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/defaulttags.py", line 862, in do_for
+ nodelist_loop = parser.parse(
+ ^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 489, in parse
+ raise self.error(token, e)
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 487, in parse
+ filter_expression = self.compile_filter(token.contents)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 609, in compile_filter
+ return FilterExpression(token, self)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 705, in __init__
+ filter_func = parser.find_filter(filter_name)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 615, in find_filter
+ raise TemplateSyntaxError("Invalid filter: '%s'" % filter_name)
+django.template.exceptions.TemplateSyntaxError: Invalid filter: 'split'
+ERROR 2025-09-07 16:36:29,883 basehttp 73004 6191345664 "GET /en/hr/training/142/ HTTP/1.1" 500 375846
+WARNING 2025-09-07 16:36:29,900 log 73004 6191345664 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 16:36:29,900 basehttp 73004 6191345664 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-07 16:36:35,163 basehttp 73004 6191345664 "GET /en/hr/training HTTP/1.1" 301 0
+ERROR 2025-09-07 16:36:35,261 log 73004 6208172032 Internal Server Error: /en/hr/training/
+Traceback (most recent call last):
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/core/handlers/exception.py", line 55, in inner
+ response = get_response(request)
+ ^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/core/handlers/base.py", line 220, in _get_response
+ response = response.render()
+ ^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/response.py", line 114, in render
+ self.content = self.rendered_content
+ ^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/response.py", line 92, in rendered_content
+ return template.render(context, self._request)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/backends/django.py", line 107, in render
+ return self.template.render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 171, in render
+ return self._render(context)
+ ^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 163, in _render
+ return self.nodelist.render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 1016, in render
+ return SafeString("".join([node.render_annotated(context) for node in self]))
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 977, in render_annotated
+ return self.render(context)
+ ^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/loader_tags.py", line 159, in render
+ return compiled_parent._render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 163, in _render
+ return self.nodelist.render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 1016, in render
+ return SafeString("".join([node.render_annotated(context) for node in self]))
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 977, in render_annotated
+ return self.render(context)
+ ^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/loader_tags.py", line 65, in render
+ result = block.nodelist.render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 1016, in render
+ return SafeString("".join([node.render_annotated(context) for node in self]))
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 977, in render_annotated
+ return self.render(context)
+ ^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/defaulttags.py", line 480, in render
+ url = reverse(view_name, args=args, kwargs=kwargs, current_app=current_app)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/urls/base.py", line 98, in reverse
+ resolved_url = resolver._reverse_with_prefix(view, prefix, *args, **kwargs)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/urls/resolvers.py", line 831, in _reverse_with_prefix
+ raise NoReverseMatch(msg)
+django.urls.exceptions.NoReverseMatch: Reverse for 'get_program_details' not found. 'get_program_details' is not a valid view function or pattern name.
+ERROR 2025-09-07 16:36:35,262 basehttp 73004 6208172032 "GET /en/hr/training/ HTTP/1.1" 500 215315
+WARNING 2025-09-07 16:36:35,282 log 73004 6208172032 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 16:36:35,282 basehttp 73004 6208172032 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+ERROR 2025-09-07 16:40:38,449 log 73004 6208172032 Internal Server Error: /en/hr/training/
+Traceback (most recent call last):
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/core/handlers/exception.py", line 55, in inner
+ response = get_response(request)
+ ^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/core/handlers/base.py", line 220, in _get_response
+ response = response.render()
+ ^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/response.py", line 114, in render
+ self.content = self.rendered_content
+ ^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/response.py", line 92, in rendered_content
+ return template.render(context, self._request)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/backends/django.py", line 107, in render
+ return self.template.render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 171, in render
+ return self._render(context)
+ ^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 163, in _render
+ return self.nodelist.render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 1016, in render
+ return SafeString("".join([node.render_annotated(context) for node in self]))
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 977, in render_annotated
+ return self.render(context)
+ ^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/loader_tags.py", line 159, in render
+ return compiled_parent._render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 163, in _render
+ return self.nodelist.render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 1016, in render
+ return SafeString("".join([node.render_annotated(context) for node in self]))
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 977, in render_annotated
+ return self.render(context)
+ ^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/loader_tags.py", line 65, in render
+ result = block.nodelist.render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 1016, in render
+ return SafeString("".join([node.render_annotated(context) for node in self]))
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 977, in render_annotated
+ return self.render(context)
+ ^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/defaulttags.py", line 480, in render
+ url = reverse(view_name, args=args, kwargs=kwargs, current_app=current_app)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/urls/base.py", line 98, in reverse
+ resolved_url = resolver._reverse_with_prefix(view, prefix, *args, **kwargs)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/urls/resolvers.py", line 831, in _reverse_with_prefix
+ raise NoReverseMatch(msg)
+django.urls.exceptions.NoReverseMatch: Reverse for 'update_program' not found. 'update_program' is not a valid view function or pattern name.
+ERROR 2025-09-07 16:40:38,450 basehttp 73004 6208172032 "GET /en/hr/training/ HTTP/1.1" 500 217002
+WARNING 2025-09-07 16:40:38,462 log 73004 6208172032 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 16:40:38,462 basehttp 73004 6208172032 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+ERROR 2025-09-07 16:41:03,400 log 73004 6208172032 Internal Server Error: /en/hr/training/
+Traceback (most recent call last):
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/core/handlers/exception.py", line 55, in inner
+ response = get_response(request)
+ ^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/core/handlers/base.py", line 220, in _get_response
+ response = response.render()
+ ^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/response.py", line 114, in render
+ self.content = self.rendered_content
+ ^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/response.py", line 92, in rendered_content
+ return template.render(context, self._request)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/backends/django.py", line 107, in render
+ return self.template.render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 171, in render
+ return self._render(context)
+ ^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 163, in _render
+ return self.nodelist.render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 1016, in render
+ return SafeString("".join([node.render_annotated(context) for node in self]))
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 977, in render_annotated
+ return self.render(context)
+ ^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/loader_tags.py", line 159, in render
+ return compiled_parent._render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 163, in _render
+ return self.nodelist.render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 1016, in render
+ return SafeString("".join([node.render_annotated(context) for node in self]))
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 977, in render_annotated
+ return self.render(context)
+ ^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/loader_tags.py", line 65, in render
+ result = block.nodelist.render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 1016, in render
+ return SafeString("".join([node.render_annotated(context) for node in self]))
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 977, in render_annotated
+ return self.render(context)
+ ^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/defaulttags.py", line 480, in render
+ url = reverse(view_name, args=args, kwargs=kwargs, current_app=current_app)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/urls/base.py", line 98, in reverse
+ resolved_url = resolver._reverse_with_prefix(view, prefix, *args, **kwargs)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/urls/resolvers.py", line 831, in _reverse_with_prefix
+ raise NoReverseMatch(msg)
+django.urls.exceptions.NoReverseMatch: Reverse for 'program_detail' not found. 'program_detail' is not a valid view function or pattern name.
+ERROR 2025-09-07 16:41:03,401 basehttp 73004 6208172032 "GET /en/hr/training/ HTTP/1.1" 500 217084
+WARNING 2025-09-07 16:41:03,420 log 73004 6208172032 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 16:41:03,420 basehttp 73004 6208172032 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-07 16:43:49,987 basehttp 73004 6208172032 "GET /en/hr/training/ HTTP/1.1" 200 51267
+WARNING 2025-09-07 16:43:50,002 log 73004 6208172032 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 16:43:50,003 basehttp 73004 6208172032 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-07 16:43:50,050 basehttp 73004 6208172032 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 16:44:50,053 basehttp 73004 6208172032 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 16:45:14,901 autoreload 73004 8747049152 /Users/marwanalwali/manus_project/hospital_management_system_v4/hr/views.py changed, reloading.
+INFO 2025-09-07 16:45:15,356 autoreload 76878 8747049152 Watching for file changes with StatReloader
+INFO 2025-09-07 16:45:16,032 basehttp 76878 6132101120 "GET /en/hr/training/ HTTP/1.1" 200 117087
+WARNING 2025-09-07 16:45:16,050 log 76878 6132101120 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 16:45:16,050 basehttp 76878 6132101120 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-07 16:45:16,113 basehttp 76878 6132101120 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+WARNING 2025-09-07 16:45:35,524 log 76878 6132101120 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 16:45:35,524 basehttp 76878 6132101120 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+WARNING 2025-09-07 16:45:40,288 log 76878 6132101120 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 16:45:40,289 basehttp 76878 6132101120 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-07 16:45:43,734 basehttp 76878 6132101120 "GET /en/hr/ HTTP/1.1" 200 42394
+WARNING 2025-09-07 16:45:43,749 log 76878 6132101120 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 16:45:43,750 basehttp 76878 6132101120 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-07 16:45:43,797 basehttp 76878 6132101120 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 16:45:54,662 basehttp 76878 6132101120 "GET /en/hr/training/ HTTP/1.1" 200 117087
+WARNING 2025-09-07 16:45:54,680 log 76878 6132101120 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 16:45:54,680 basehttp 76878 6132101120 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-07 16:45:54,737 basehttp 76878 6132101120 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+WARNING 2025-09-07 16:45:56,841 log 76878 6132101120 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 16:45:56,842 basehttp 76878 6132101120 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+WARNING 2025-09-07 16:45:56,881 log 76878 6132101120 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 16:45:56,881 basehttp 76878 6132101120 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-07 16:46:43,810 basehttp 76878 6132101120 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 16:47:43,813 basehttp 76878 6132101120 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 16:47:44,830 basehttp 76878 6132101120 "GET /en/hr/ HTTP/1.1" 200 42394
+WARNING 2025-09-07 16:47:44,846 log 76878 6132101120 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 16:47:44,846 basehttp 76878 6132101120 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-07 16:47:44,893 basehttp 76878 6132101120 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 16:48:44,905 basehttp 76878 6132101120 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 16:49:35,670 autoreload 76878 8747049152 /Users/marwanalwali/manus_project/hospital_management_system_v4/hr/views.py changed, reloading.
+INFO 2025-09-07 16:49:35,990 autoreload 78804 8747049152 Watching for file changes with StatReloader
+WARNING 2025-09-07 16:49:37,066 log 78804 6140686336 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 16:49:37,066 basehttp 78804 6140686336 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-07 16:49:37,106 basehttp 78804 6123859968 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+WARNING 2025-09-07 16:49:37,137 log 78804 6123859968 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 16:49:37,137 basehttp 78804 6123859968 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+WARNING 2025-09-07 16:49:38,055 log 78804 6123859968 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 16:49:38,055 basehttp 78804 6123859968 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+WARNING 2025-09-07 16:49:38,064 log 78804 6123859968 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 16:49:38,064 basehttp 78804 6123859968 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-07 16:49:38,551 basehttp 78804 6123859968 "GET /en/hr/ HTTP/1.1" 200 42394
+WARNING 2025-09-07 16:49:38,562 log 78804 6123859968 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 16:49:38,563 basehttp 78804 6123859968 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-07 16:49:38,611 basehttp 78804 6123859968 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+WARNING 2025-09-07 16:49:40,061 log 78804 6123859968 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 16:49:40,061 basehttp 78804 6123859968 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+WARNING 2025-09-07 16:49:40,074 log 78804 6123859968 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 16:49:40,075 basehttp 78804 6123859968 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-07 16:49:40,983 basehttp 78804 6123859968 "GET /en/hr/training/ HTTP/1.1" 200 51267
+WARNING 2025-09-07 16:49:41,003 log 78804 6123859968 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 16:49:41,003 basehttp 78804 6123859968 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-07 16:49:41,049 basehttp 78804 6123859968 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 16:50:41,063 basehttp 78804 6123859968 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 16:51:41,068 basehttp 78804 6123859968 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 16:52:41,094 basehttp 78804 6123859968 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 16:53:42,091 basehttp 78804 6123859968 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 16:54:43,092 basehttp 78804 6123859968 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 16:55:44,095 basehttp 78804 6123859968 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 16:56:46,088 basehttp 78804 6123859968 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 16:58:09,082 basehttp 78804 6123859968 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 17:00:09,077 basehttp 78804 6123859968 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 17:02:09,203 basehttp 78804 6123859968 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 17:02:22,937 autoreload 78804 8747049152 /Users/marwanalwali/manus_project/hospital_management_system_v4/hr/views.py changed, reloading.
+INFO 2025-09-07 17:02:23,361 autoreload 84426 8747049152 Watching for file changes with StatReloader
+INFO 2025-09-07 17:02:36,218 basehttp 84426 6157742080 "GET /en/hr/training/ HTTP/1.1" 200 94607
+WARNING 2025-09-07 17:02:36,238 log 84426 6157742080 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 17:02:36,238 basehttp 84426 6157742080 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-07 17:02:36,328 basehttp 84426 6157742080 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+ERROR 2025-09-07 17:02:59,699 log 84426 6157742080 Internal Server Error: /en/hr/training/642/
+Traceback (most recent call last):
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/core/handlers/exception.py", line 55, in inner
+ response = get_response(request)
+ ^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/core/handlers/base.py", line 220, in _get_response
+ response = response.render()
+ ^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/response.py", line 114, in render
+ self.content = self.rendered_content
+ ^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/response.py", line 90, in rendered_content
+ template = self.resolve_template(self.template_name)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/response.py", line 72, in resolve_template
+ return select_template(template, using=self.using)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/loader.py", line 42, in select_template
+ return engine.get_template(template_name)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/backends/django.py", line 79, in get_template
+ return Template(self.engine.get_template(template_name), self)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/engine.py", line 177, in get_template
+ template, origin = self.find_template(template_name)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/engine.py", line 159, in find_template
+ template = loader.get_template(name, skip=skip)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/loaders/cached.py", line 57, in get_template
+ template = super().get_template(template_name, skip)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/loaders/base.py", line 28, in get_template
+ return Template(
+ ^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 154, in __init__
+ self.nodelist = self.compile_nodelist()
+ ^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 196, in compile_nodelist
+ nodelist = parser.parse()
+ ^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 518, in parse
+ raise self.error(token, e)
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 516, in parse
+ compiled_result = compile_func(self, token)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/loader_tags.py", line 299, in do_extends
+ nodelist = parser.parse()
+ ^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 518, in parse
+ raise self.error(token, e)
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 516, in parse
+ compiled_result = compile_func(self, token)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/loader_tags.py", line 234, in do_block
+ nodelist = parser.parse(("endblock",))
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 518, in parse
+ raise self.error(token, e)
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 516, in parse
+ compiled_result = compile_func(self, token)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/defaulttags.py", line 962, in do_if
+ nodelist = parser.parse(("elif", "else", "endif"))
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 518, in parse
+ raise self.error(token, e)
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 516, in parse
+ compiled_result = compile_func(self, token)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/defaulttags.py", line 962, in do_if
+ nodelist = parser.parse(("elif", "else", "endif"))
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 518, in parse
+ raise self.error(token, e)
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 516, in parse
+ compiled_result = compile_func(self, token)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/defaulttags.py", line 862, in do_for
+ nodelist_loop = parser.parse(
+ ^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 489, in parse
+ raise self.error(token, e)
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 487, in parse
+ filter_expression = self.compile_filter(token.contents)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 609, in compile_filter
+ return FilterExpression(token, self)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 705, in __init__
+ filter_func = parser.find_filter(filter_name)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 615, in find_filter
+ raise TemplateSyntaxError("Invalid filter: '%s'" % filter_name)
+django.template.exceptions.TemplateSyntaxError: Invalid filter: 'split'
+ERROR 2025-09-07 17:02:59,703 basehttp 84426 6157742080 "GET /en/hr/training/642/ HTTP/1.1" 500 375709
+WARNING 2025-09-07 17:02:59,716 log 84426 6157742080 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 17:02:59,716 basehttp 84426 6157742080 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+WARNING 2025-09-07 17:03:56,329 log 84426 6325039104 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 17:03:56,330 basehttp 84426 6325039104 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-07 17:03:56,331 basehttp 84426 6157742080 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+WARNING 2025-09-07 17:03:56,341 log 84426 6157742080 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 17:03:56,341 basehttp 84426 6157742080 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-07 17:03:57,012 basehttp 84426 6157742080 "GET /en/hr/training/ HTTP/1.1" 200 94613
+WARNING 2025-09-07 17:03:57,026 log 84426 6157742080 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 17:03:57,026 basehttp 84426 6157742080 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-07 17:03:57,107 basehttp 84426 6157742080 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+ERROR 2025-09-07 17:04:41,775 log 84426 6157742080 Internal Server Error: /en/hr/training/313/
+Traceback (most recent call last):
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 510, in parse
+ compile_func = self.tags[command]
+ ~~~~~~~~~^^^^^^^^^
+KeyError: "set_badge='success'"
+
+During handling of the above exception, another exception occurred:
+
+Traceback (most recent call last):
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/core/handlers/exception.py", line 55, in inner
+ response = get_response(request)
+ ^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/core/handlers/base.py", line 220, in _get_response
+ response = response.render()
+ ^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/response.py", line 114, in render
+ self.content = self.rendered_content
+ ^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/response.py", line 90, in rendered_content
+ template = self.resolve_template(self.template_name)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/response.py", line 72, in resolve_template
+ return select_template(template, using=self.using)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/loader.py", line 42, in select_template
+ return engine.get_template(template_name)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/backends/django.py", line 79, in get_template
+ return Template(self.engine.get_template(template_name), self)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/engine.py", line 177, in get_template
+ template, origin = self.find_template(template_name)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/engine.py", line 159, in find_template
+ template = loader.get_template(name, skip=skip)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/loaders/cached.py", line 57, in get_template
+ template = super().get_template(template_name, skip)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/loaders/base.py", line 28, in get_template
+ return Template(
+ ^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 154, in __init__
+ self.nodelist = self.compile_nodelist()
+ ^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 196, in compile_nodelist
+ nodelist = parser.parse()
+ ^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 518, in parse
+ raise self.error(token, e)
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 516, in parse
+ compiled_result = compile_func(self, token)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/loader_tags.py", line 299, in do_extends
+ nodelist = parser.parse()
+ ^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 518, in parse
+ raise self.error(token, e)
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 516, in parse
+ compiled_result = compile_func(self, token)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/loader_tags.py", line 234, in do_block
+ nodelist = parser.parse(("endblock",))
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 518, in parse
+ raise self.error(token, e)
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 516, in parse
+ compiled_result = compile_func(self, token)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/defaulttags.py", line 1540, in do_with
+ nodelist = parser.parse(("endwith",))
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 518, in parse
+ raise self.error(token, e)
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 516, in parse
+ compiled_result = compile_func(self, token)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/defaulttags.py", line 962, in do_if
+ nodelist = parser.parse(("elif", "else", "endif"))
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 512, in parse
+ self.invalid_block_tag(token, command, parse_until)
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 567, in invalid_block_tag
+ raise self.error(
+django.template.exceptions.TemplateSyntaxError: Invalid block tag on line 48: 'set_badge='success'', expected 'elif', 'else' or 'endif'. Did you forget to register or load this tag?
+ERROR 2025-09-07 17:04:41,778 basehttp 84426 6157742080 "GET /en/hr/training/313/ HTTP/1.1" 500 314845
+WARNING 2025-09-07 17:04:41,793 log 84426 6157742080 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 17:04:41,793 basehttp 84426 6157742080 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+WARNING 2025-09-07 17:04:47,934 log 84426 6157742080 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 17:04:47,934 basehttp 84426 6157742080 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+WARNING 2025-09-07 17:04:47,946 log 84426 6157742080 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 17:04:47,946 basehttp 84426 6157742080 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-07 17:04:57,134 basehttp 84426 6157742080 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+ERROR 2025-09-07 17:05:08,240 log 84426 6157742080 Internal Server Error: /en/hr/training/9/
+Traceback (most recent call last):
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/core/handlers/exception.py", line 55, in inner
+ response = get_response(request)
+ ^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/core/handlers/base.py", line 220, in _get_response
+ response = response.render()
+ ^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/response.py", line 114, in render
+ self.content = self.rendered_content
+ ^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/response.py", line 90, in rendered_content
+ template = self.resolve_template(self.template_name)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/response.py", line 72, in resolve_template
+ return select_template(template, using=self.using)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/loader.py", line 42, in select_template
+ return engine.get_template(template_name)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/backends/django.py", line 79, in get_template
+ return Template(self.engine.get_template(template_name), self)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/engine.py", line 177, in get_template
+ template, origin = self.find_template(template_name)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/engine.py", line 159, in find_template
+ template = loader.get_template(name, skip=skip)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/loaders/cached.py", line 57, in get_template
+ template = super().get_template(template_name, skip)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/loaders/base.py", line 28, in get_template
+ return Template(
+ ^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 154, in __init__
+ self.nodelist = self.compile_nodelist()
+ ^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 196, in compile_nodelist
+ nodelist = parser.parse()
+ ^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 518, in parse
+ raise self.error(token, e)
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 516, in parse
+ compiled_result = compile_func(self, token)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/loader_tags.py", line 299, in do_extends
+ nodelist = parser.parse()
+ ^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 518, in parse
+ raise self.error(token, e)
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 516, in parse
+ compiled_result = compile_func(self, token)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/loader_tags.py", line 234, in do_block
+ nodelist = parser.parse(("endblock",))
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 518, in parse
+ raise self.error(token, e)
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 516, in parse
+ compiled_result = compile_func(self, token)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/defaulttags.py", line 962, in do_if
+ nodelist = parser.parse(("elif", "else", "endif"))
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 518, in parse
+ raise self.error(token, e)
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 516, in parse
+ compiled_result = compile_func(self, token)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/defaulttags.py", line 962, in do_if
+ nodelist = parser.parse(("elif", "else", "endif"))
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 518, in parse
+ raise self.error(token, e)
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 516, in parse
+ compiled_result = compile_func(self, token)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/defaulttags.py", line 862, in do_for
+ nodelist_loop = parser.parse(
+ ^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 489, in parse
+ raise self.error(token, e)
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 487, in parse
+ filter_expression = self.compile_filter(token.contents)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 609, in compile_filter
+ return FilterExpression(token, self)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 705, in __init__
+ filter_func = parser.find_filter(filter_name)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 615, in find_filter
+ raise TemplateSyntaxError("Invalid filter: '%s'" % filter_name)
+django.template.exceptions.TemplateSyntaxError: Invalid filter: 'split'
+ERROR 2025-09-07 17:05:08,242 basehttp 84426 6157742080 "GET /en/hr/training/9/ HTTP/1.1" 500 375659
+WARNING 2025-09-07 17:05:08,256 log 84426 6157742080 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 17:05:08,256 basehttp 84426 6157742080 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+ERROR 2025-09-07 17:05:28,071 log 84426 6157742080 Internal Server Error: /en/hr/training/9/
+Traceback (most recent call last):
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/core/handlers/exception.py", line 55, in inner
+ response = get_response(request)
+ ^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/core/handlers/base.py", line 220, in _get_response
+ response = response.render()
+ ^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/response.py", line 114, in render
+ self.content = self.rendered_content
+ ^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/response.py", line 90, in rendered_content
+ template = self.resolve_template(self.template_name)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/response.py", line 72, in resolve_template
+ return select_template(template, using=self.using)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/loader.py", line 42, in select_template
+ return engine.get_template(template_name)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/backends/django.py", line 79, in get_template
+ return Template(self.engine.get_template(template_name), self)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/engine.py", line 177, in get_template
+ template, origin = self.find_template(template_name)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/engine.py", line 159, in find_template
+ template = loader.get_template(name, skip=skip)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/loaders/cached.py", line 57, in get_template
+ template = super().get_template(template_name, skip)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/loaders/base.py", line 28, in get_template
+ return Template(
+ ^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 154, in __init__
+ self.nodelist = self.compile_nodelist()
+ ^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 196, in compile_nodelist
+ nodelist = parser.parse()
+ ^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 518, in parse
+ raise self.error(token, e)
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 516, in parse
+ compiled_result = compile_func(self, token)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/loader_tags.py", line 299, in do_extends
+ nodelist = parser.parse()
+ ^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 518, in parse
+ raise self.error(token, e)
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 516, in parse
+ compiled_result = compile_func(self, token)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/loader_tags.py", line 234, in do_block
+ nodelist = parser.parse(("endblock",))
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 518, in parse
+ raise self.error(token, e)
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 516, in parse
+ compiled_result = compile_func(self, token)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/defaulttags.py", line 962, in do_if
+ nodelist = parser.parse(("elif", "else", "endif"))
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 518, in parse
+ raise self.error(token, e)
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 516, in parse
+ compiled_result = compile_func(self, token)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/defaulttags.py", line 862, in do_for
+ nodelist_loop = parser.parse(
+ ^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 489, in parse
+ raise self.error(token, e)
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 487, in parse
+ filter_expression = self.compile_filter(token.contents)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 609, in compile_filter
+ return FilterExpression(token, self)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 705, in __init__
+ filter_func = parser.find_filter(filter_name)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 615, in find_filter
+ raise TemplateSyntaxError("Invalid filter: '%s'" % filter_name)
+django.template.exceptions.TemplateSyntaxError: Invalid filter: 'split'
+ERROR 2025-09-07 17:05:28,073 basehttp 84426 6157742080 "GET /en/hr/training/9/ HTTP/1.1" 500 320532
+WARNING 2025-09-07 17:05:28,089 log 84426 6157742080 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 17:05:28,089 basehttp 84426 6157742080 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+ERROR 2025-09-07 17:05:40,036 log 84426 6157742080 Internal Server Error: /en/hr/training/9/
+Traceback (most recent call last):
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/core/handlers/exception.py", line 55, in inner
+ response = get_response(request)
+ ^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/core/handlers/base.py", line 220, in _get_response
+ response = response.render()
+ ^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/response.py", line 114, in render
+ self.content = self.rendered_content
+ ^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/response.py", line 92, in rendered_content
+ return template.render(context, self._request)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/backends/django.py", line 107, in render
+ return self.template.render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 171, in render
+ return self._render(context)
+ ^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 163, in _render
+ return self.nodelist.render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 1016, in render
+ return SafeString("".join([node.render_annotated(context) for node in self]))
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 977, in render_annotated
+ return self.render(context)
+ ^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/loader_tags.py", line 159, in render
+ return compiled_parent._render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 163, in _render
+ return self.nodelist.render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 1016, in render
+ return SafeString("".join([node.render_annotated(context) for node in self]))
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 977, in render_annotated
+ return self.render(context)
+ ^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/loader_tags.py", line 65, in render
+ result = block.nodelist.render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 1016, in render
+ return SafeString("".join([node.render_annotated(context) for node in self]))
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 977, in render_annotated
+ return self.render(context)
+ ^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/defaulttags.py", line 480, in render
+ url = reverse(view_name, args=args, kwargs=kwargs, current_app=current_app)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/urls/base.py", line 98, in reverse
+ resolved_url = resolver._reverse_with_prefix(view, prefix, *args, **kwargs)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/urls/resolvers.py", line 831, in _reverse_with_prefix
+ raise NoReverseMatch(msg)
+django.urls.exceptions.NoReverseMatch: Reverse for 'employee_detail' with arguments '('',)' not found. 1 pattern(s) tried: ['en/hr/employees/(?P[0-9]+)/\\Z']
+ERROR 2025-09-07 17:05:40,038 basehttp 84426 6157742080 "GET /en/hr/training/9/ HTTP/1.1" 500 179703
+WARNING 2025-09-07 17:05:40,051 log 84426 6157742080 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 17:05:40,051 basehttp 84426 6157742080 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+ERROR 2025-09-07 17:06:30,036 log 84426 6157742080 Internal Server Error: /en/hr/training/9/
+Traceback (most recent call last):
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/core/handlers/exception.py", line 55, in inner
+ response = get_response(request)
+ ^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/core/handlers/base.py", line 220, in _get_response
+ response = response.render()
+ ^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/response.py", line 114, in render
+ self.content = self.rendered_content
+ ^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/response.py", line 92, in rendered_content
+ return template.render(context, self._request)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/backends/django.py", line 107, in render
+ return self.template.render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 171, in render
+ return self._render(context)
+ ^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 163, in _render
+ return self.nodelist.render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 1016, in render
+ return SafeString("".join([node.render_annotated(context) for node in self]))
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 977, in render_annotated
+ return self.render(context)
+ ^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/loader_tags.py", line 159, in render
+ return compiled_parent._render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 163, in _render
+ return self.nodelist.render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 1016, in render
+ return SafeString("".join([node.render_annotated(context) for node in self]))
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 977, in render_annotated
+ return self.render(context)
+ ^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/loader_tags.py", line 65, in render
+ result = block.nodelist.render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 1016, in render
+ return SafeString("".join([node.render_annotated(context) for node in self]))
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 977, in render_annotated
+ return self.render(context)
+ ^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/defaulttags.py", line 480, in render
+ url = reverse(view_name, args=args, kwargs=kwargs, current_app=current_app)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/urls/base.py", line 98, in reverse
+ resolved_url = resolver._reverse_with_prefix(view, prefix, *args, **kwargs)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/urls/resolvers.py", line 831, in _reverse_with_prefix
+ raise NoReverseMatch(msg)
+django.urls.exceptions.NoReverseMatch: Reverse for 'employee_detail' with arguments '('',)' not found. 1 pattern(s) tried: ['en/hr/employees/(?P[0-9]+)/\\Z']
+ERROR 2025-09-07 17:06:30,037 basehttp 84426 6157742080 "GET /en/hr/training/9/ HTTP/1.1" 500 179703
+WARNING 2025-09-07 17:06:30,049 log 84426 6157742080 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 17:06:30,049 basehttp 84426 6157742080 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+WARNING 2025-09-07 17:13:58,575 log 84426 6325039104 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 17:13:58,575 basehttp 84426 6325039104 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-07 17:13:58,579 basehttp 84426 6157742080 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+WARNING 2025-09-07 17:13:58,583 log 84426 6325039104 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 17:13:58,583 basehttp 84426 6325039104 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-07 17:14:58,570 basehttp 84426 6325039104 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 17:15:00,153 basehttp 84426 6325039104 "GET /en/blood-bank/ HTTP/1.1" 200 121063
+INFO 2025-09-07 17:15:00,213 basehttp 84426 6325039104 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 17:15:07,473 basehttp 84426 6325039104 "GET /en/blood-bank/units/38/ HTTP/1.1" 200 35788
+INFO 2025-09-07 17:15:07,484 basehttp 84426 6325039104 "GET /static/plugins/sweetalert/dist/sweetalert.min.js HTTP/1.1" 200 40808
+INFO 2025-09-07 17:15:07,520 basehttp 84426 6325039104 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 17:15:14,164 basehttp 84426 6325039104 "GET /en/blood-bank/units/38/test/ HTTP/1.1" 200 45659
+INFO 2025-09-07 17:15:14,194 basehttp 84426 6325039104 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 17:15:21,406 basehttp 84426 6325039104 "GET /en/blood-bank/donors/46/ HTTP/1.1" 200 29824
+INFO 2025-09-07 17:15:21,443 basehttp 84426 6325039104 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 17:15:26,546 basehttp 84426 6325039104 "GET /en/blood-bank/donors/46/eligibility/ HTTP/1.1" 200 33976
+INFO 2025-09-07 17:15:26,582 basehttp 84426 6325039104 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 17:16:06,428 basehttp 84426 6157742080 "GET /en/blood-bank/donors/46/eligibility/ HTTP/1.1" 200 33976
+INFO 2025-09-07 17:16:06,466 basehttp 84426 6157742080 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 17:16:27,765 basehttp 84426 6157742080 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 17:16:30,194 basehttp 84426 6157742080 "GET /en/blood-bank/units/13/ HTTP/1.1" 200 36506
+INFO 2025-09-07 17:16:30,234 basehttp 84426 6157742080 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 17:16:47,814 basehttp 84426 6157742080 "GET /en/blood-bank/donors/46/eligibility/ HTTP/1.1" 200 33976
+INFO 2025-09-07 17:16:47,852 basehttp 84426 6157742080 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 17:16:55,138 basehttp 84426 6157742080 "GET /en/blood-bank/donors/ HTTP/1.1" 200 82651
+INFO 2025-09-07 17:16:55,182 basehttp 84426 6157742080 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 17:17:08,876 basehttp 84426 6157742080 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 17:17:24,261 basehttp 84426 6157742080 "GET /en/blood-bank/inventory/ HTTP/1.1" 200 34369
+INFO 2025-09-07 17:17:24,299 basehttp 84426 6157742080 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 17:17:43,987 basehttp 84426 6157742080 "GET /en/blood-bank/donors/ HTTP/1.1" 200 82651
+INFO 2025-09-07 17:17:44,028 basehttp 84426 6157742080 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 17:17:49,526 basehttp 84426 6157742080 "GET /en/blood-bank/units/create/ HTTP/1.1" 200 56247
+INFO 2025-09-07 17:17:49,534 basehttp 84426 6157742080 "GET /static/plugins/bootstrap-datepicker/dist/css/bootstrap-datepicker.min.css HTTP/1.1" 200 15733
+INFO 2025-09-07 17:17:49,534 basehttp 84426 6325039104 "GET /static/plugins/bootstrap-datepicker/dist/js/bootstrap-datepicker.min.js HTTP/1.1" 200 33871
+INFO 2025-09-07 17:17:49,565 basehttp 84426 6325039104 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 17:18:49,580 basehttp 84426 6325039104 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 17:19:49,585 basehttp 84426 6325039104 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 17:20:49,583 basehttp 84426 6325039104 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 17:21:17,193 basehttp 84426 6325039104 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 17:21:17,777 basehttp 84426 6325039104 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 17:21:23,031 basehttp 84426 6325039104 "GET /en/hr/training/ HTTP/1.1" 200 94613
+INFO 2025-09-07 17:21:23,076 basehttp 84426 6325039104 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+ERROR 2025-09-07 17:21:24,288 log 84426 6325039104 Internal Server Error: /en/hr/training/9/
+Traceback (most recent call last):
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/core/handlers/exception.py", line 55, in inner
+ response = get_response(request)
+ ^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/core/handlers/base.py", line 220, in _get_response
+ response = response.render()
+ ^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/response.py", line 114, in render
+ self.content = self.rendered_content
+ ^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/response.py", line 92, in rendered_content
+ return template.render(context, self._request)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/backends/django.py", line 107, in render
+ return self.template.render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 171, in render
+ return self._render(context)
+ ^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 163, in _render
+ return self.nodelist.render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 1016, in render
+ return SafeString("".join([node.render_annotated(context) for node in self]))
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 977, in render_annotated
+ return self.render(context)
+ ^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/loader_tags.py", line 159, in render
+ return compiled_parent._render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 163, in _render
+ return self.nodelist.render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 1016, in render
+ return SafeString("".join([node.render_annotated(context) for node in self]))
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 977, in render_annotated
+ return self.render(context)
+ ^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/loader_tags.py", line 65, in render
+ result = block.nodelist.render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 1016, in render
+ return SafeString("".join([node.render_annotated(context) for node in self]))
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 977, in render_annotated
+ return self.render(context)
+ ^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/defaulttags.py", line 480, in render
+ url = reverse(view_name, args=args, kwargs=kwargs, current_app=current_app)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/urls/base.py", line 98, in reverse
+ resolved_url = resolver._reverse_with_prefix(view, prefix, *args, **kwargs)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/urls/resolvers.py", line 831, in _reverse_with_prefix
+ raise NoReverseMatch(msg)
+django.urls.exceptions.NoReverseMatch: Reverse for 'employee_detail' with arguments '('',)' not found. 1 pattern(s) tried: ['en/hr/employees/(?P[0-9]+)/\\Z']
+ERROR 2025-09-07 17:21:24,291 basehttp 84426 6325039104 "GET /en/hr/training/9/ HTTP/1.1" 500 179587
+INFO 2025-09-07 17:22:23,081 basehttp 84426 6325039104 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 17:22:49,206 autoreload 84426 8747049152 /Users/marwanalwali/manus_project/hospital_management_system_v4/hr/views.py changed, reloading.
+INFO 2025-09-07 17:22:49,647 autoreload 93365 8747049152 Watching for file changes with StatReloader
+ERROR 2025-09-07 17:22:52,504 log 93365 6132805632 Internal Server Error: /en/hr/training/9/
+Traceback (most recent call last):
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/core/handlers/exception.py", line 55, in inner
+ response = get_response(request)
+ ^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/core/handlers/base.py", line 220, in _get_response
+ response = response.render()
+ ^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/response.py", line 114, in render
+ self.content = self.rendered_content
+ ^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/response.py", line 92, in rendered_content
+ return template.render(context, self._request)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/backends/django.py", line 107, in render
+ return self.template.render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 171, in render
+ return self._render(context)
+ ^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 163, in _render
+ return self.nodelist.render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 1016, in render
+ return SafeString("".join([node.render_annotated(context) for node in self]))
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 977, in render_annotated
+ return self.render(context)
+ ^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/loader_tags.py", line 159, in render
+ return compiled_parent._render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 163, in _render
+ return self.nodelist.render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 1016, in render
+ return SafeString("".join([node.render_annotated(context) for node in self]))
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 977, in render_annotated
+ return self.render(context)
+ ^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/loader_tags.py", line 65, in render
+ result = block.nodelist.render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 1016, in render
+ return SafeString("".join([node.render_annotated(context) for node in self]))
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 977, in render_annotated
+ return self.render(context)
+ ^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/defaulttags.py", line 480, in render
+ url = reverse(view_name, args=args, kwargs=kwargs, current_app=current_app)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/urls/base.py", line 98, in reverse
+ resolved_url = resolver._reverse_with_prefix(view, prefix, *args, **kwargs)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/urls/resolvers.py", line 831, in _reverse_with_prefix
+ raise NoReverseMatch(msg)
+django.urls.exceptions.NoReverseMatch: Reverse for 'training_record_print' not found. 'training_record_print' is not a valid view function or pattern name.
+ERROR 2025-09-07 17:22:52,506 basehttp 93365 6132805632 "GET /en/hr/training/9/ HTTP/1.1" 500 177519
+INFO 2025-09-07 17:23:43,843 basehttp 93365 6132805632 "GET /en/hr/training/9/ HTTP/1.1" 200 28657
+INFO 2025-09-07 17:23:43,879 basehttp 93365 6132805632 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 17:24:43,895 basehttp 93365 6132805632 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 17:24:50,025 basehttp 93365 6132805632 "GET /en/hr/training/9/ HTTP/1.1" 200 28729
+INFO 2025-09-07 17:24:50,064 basehttp 93365 6132805632 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 17:25:18,410 basehttp 93365 6132805632 "GET /en/hr/training/9/ HTTP/1.1" 200 28765
+INFO 2025-09-07 17:25:18,451 basehttp 93365 6132805632 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 17:26:03,810 basehttp 93365 6132805632 "GET /en/hr/training/9/ HTTP/1.1" 200 28800
+INFO 2025-09-07 17:26:03,849 basehttp 93365 6132805632 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 17:27:03,861 basehttp 93365 6132805632 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 17:28:03,865 basehttp 93365 6132805632 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 17:29:21,091 autoreload 96269 8747049152 Watching for file changes with StatReloader
+INFO 2025-09-07 17:29:32,040 basehttp 96269 6134935552 "GET /en/hr/training/9/ HTTP/1.1" 200 28800
+INFO 2025-09-07 17:29:32,081 basehttp 96269 6134935552 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 17:30:12,259 basehttp 96269 6134935552 "GET /en/hr/employees/1/ HTTP/1.1" 200 35234
+INFO 2025-09-07 17:30:12,298 basehttp 96269 6134935552 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 17:30:32,087 basehttp 96269 6134935552 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 17:31:32,094 basehttp 96269 6134935552 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 17:32:16,229 basehttp 96269 6134935552 "GET /en/hr/training/9/ HTTP/1.1" 200 28824
+INFO 2025-09-07 17:32:16,268 basehttp 96269 6134935552 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 17:32:52,240 basehttp 96269 6134935552 "GET /en/hr/training/9/ HTTP/1.1" 200 28891
+INFO 2025-09-07 17:32:52,278 basehttp 96269 6134935552 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 17:33:52,295 basehttp 96269 6134935552 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 17:34:52,286 basehttp 96269 6134935552 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 17:35:52,294 basehttp 96269 6134935552 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 17:36:52,299 basehttp 96269 6134935552 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 17:37:52,303 basehttp 96269 6134935552 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 17:38:52,305 basehttp 96269 6134935552 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 17:39:52,308 basehttp 96269 6134935552 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 17:40:52,301 basehttp 96269 6134935552 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 17:41:52,313 basehttp 96269 6134935552 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 17:42:52,305 basehttp 96269 6134935552 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 17:43:52,316 basehttp 96269 6134935552 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 17:44:52,319 basehttp 96269 6134935552 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 17:45:52,325 basehttp 96269 6134935552 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 17:46:52,323 basehttp 96269 6134935552 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 17:47:52,321 basehttp 96269 6134935552 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 17:48:52,322 basehttp 96269 6134935552 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 17:49:52,323 basehttp 96269 6134935552 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 17:50:52,323 basehttp 96269 6134935552 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 17:51:52,326 basehttp 96269 6134935552 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 17:52:52,317 basehttp 96269 6134935552 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 17:53:52,329 basehttp 96269 6134935552 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 17:54:52,330 basehttp 96269 6134935552 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 17:55:52,336 basehttp 96269 6134935552 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 17:56:52,333 basehttp 96269 6134935552 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 17:57:52,325 basehttp 96269 6134935552 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 17:58:30,257 autoreload 96269 8747049152 /Users/marwanalwali/manus_project/hospital_management_system_v4/hr/models.py changed, reloading.
+INFO 2025-09-07 17:58:30,606 autoreload 9737 8747049152 Watching for file changes with StatReloader
+INFO 2025-09-07 17:58:31,247 basehttp 9737 6197653504 "GET /en/hr/training/9/ HTTP/1.1" 200 28891
+INFO 2025-09-07 17:58:31,281 basehttp 9737 6197653504 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 17:58:34,709 basehttp 9737 6197653504 "GET /en/hr/training/ HTTP/1.1" 200 94613
+INFO 2025-09-07 17:58:35,629 basehttp 9737 6197653504 "GET /en/hr/training/ HTTP/1.1" 200 94613
+INFO 2025-09-07 17:58:35,671 basehttp 9737 6197653504 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+ERROR 2025-09-07 17:58:40,144 log 9737 6197653504 Internal Server Error: /en/hr/training/create/
+Traceback (most recent call last):
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/core/handlers/exception.py", line 55, in inner
+ response = get_response(request)
+ ^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/core/handlers/base.py", line 220, in _get_response
+ response = response.render()
+ ^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/response.py", line 114, in render
+ self.content = self.rendered_content
+ ^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/response.py", line 90, in rendered_content
+ template = self.resolve_template(self.template_name)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/response.py", line 72, in resolve_template
+ return select_template(template, using=self.using)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/loader.py", line 42, in select_template
+ return engine.get_template(template_name)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/backends/django.py", line 79, in get_template
+ return Template(self.engine.get_template(template_name), self)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/engine.py", line 177, in get_template
+ template, origin = self.find_template(template_name)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/engine.py", line 159, in find_template
+ template = loader.get_template(name, skip=skip)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/loaders/cached.py", line 57, in get_template
+ template = super().get_template(template_name, skip)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/loaders/base.py", line 28, in get_template
+ return Template(
+ ^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 154, in __init__
+ self.nodelist = self.compile_nodelist()
+ ^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 196, in compile_nodelist
+ nodelist = parser.parse()
+ ^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 518, in parse
+ raise self.error(token, e)
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 516, in parse
+ compiled_result = compile_func(self, token)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/loader_tags.py", line 299, in do_extends
+ nodelist = parser.parse()
+ ^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 518, in parse
+ raise self.error(token, e)
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 516, in parse
+ compiled_result = compile_func(self, token)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/loader_tags.py", line 234, in do_block
+ nodelist = parser.parse(("endblock",))
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 518, in parse
+ raise self.error(token, e)
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 516, in parse
+ compiled_result = compile_func(self, token)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/defaulttags.py", line 962, in do_if
+ nodelist = parser.parse(("elif", "else", "endif"))
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 518, in parse
+ raise self.error(token, e)
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 516, in parse
+ compiled_result = compile_func(self, token)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/defaulttags.py", line 862, in do_for
+ nodelist_loop = parser.parse(
+ ^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 489, in parse
+ raise self.error(token, e)
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 487, in parse
+ filter_expression = self.compile_filter(token.contents)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 609, in compile_filter
+ return FilterExpression(token, self)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 705, in __init__
+ filter_func = parser.find_filter(filter_name)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 615, in find_filter
+ raise TemplateSyntaxError("Invalid filter: '%s'" % filter_name)
+django.template.exceptions.TemplateSyntaxError: Invalid filter: 'split'
+ERROR 2025-09-07 17:58:40,147 basehttp 9737 6197653504 "GET /en/hr/training/create/ HTTP/1.1" 500 351884
+INFO 2025-09-07 18:00:40,415 basehttp 9737 6197653504 "GET /en/hr/training/create/ HTTP/1.1" 200 50385
+INFO 2025-09-07 18:00:40,425 basehttp 9737 6197653504 "GET /static/plugins/summernote/dist/summernote-lite.css HTTP/1.1" 200 38212
+INFO 2025-09-07 18:00:40,429 basehttp 9737 6197653504 "GET /static/plugins/summernote/dist/summernote-lite.min.js HTTP/1.1" 200 186367
+INFO 2025-09-07 18:00:40,458 basehttp 9737 6197653504 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 18:00:55,121 basehttp 9737 6197653504 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 18:01:55,122 basehttp 9737 6197653504 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 18:02:55,113 basehttp 9737 6197653504 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 18:03:55,114 basehttp 9737 6197653504 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 18:04:55,114 basehttp 9737 6197653504 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 18:05:55,118 basehttp 9737 6197653504 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 18:06:47,949 autoreload 9737 8747049152 /Users/marwanalwali/manus_project/hospital_management_system_v4/hr/models.py changed, reloading.
+INFO 2025-09-07 18:06:48,365 autoreload 13342 8747049152 Watching for file changes with StatReloader
+INFO 2025-09-07 18:49:22,974 autoreload 31933 8747049152 Watching for file changes with StatReloader
+INFO 2025-09-07 18:49:25,303 basehttp 31933 6191558656 "GET /en/hr/training/ HTTP/1.1" 200 94613
+INFO 2025-09-07 18:49:25,355 basehttp 31933 6191558656 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 18:49:28,905 basehttp 31933 6191558656 "GET /en/hr/training/9/ HTTP/1.1" 200 28891
+INFO 2025-09-07 18:49:28,934 basehttp 31933 6191558656 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+WARNING 2025-09-07 18:49:33,840 log 31933 6191558656 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 18:49:33,840 basehttp 31933 6191558656 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-07 18:49:42,876 basehttp 31933 6191558656 "GET /en/hr/training/9/update/ HTTP/1.1" 200 50484
+WARNING 2025-09-07 18:49:42,892 log 31933 6191558656 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 18:49:42,892 basehttp 31933 6191558656 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-07 18:49:42,964 basehttp 31933 6191558656 "GET /static/plugins/summernote/dist/summernote-lite.css.map HTTP/1.1" 200 52049
+INFO 2025-09-07 18:49:42,973 basehttp 31933 6191558656 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 18:50:42,989 basehttp 31933 6191558656 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 18:51:42,981 basehttp 31933 6191558656 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 18:52:35,424 autoreload 31933 8747049152 /Users/marwanalwali/manus_project/hospital_management_system_v4/hr/models.py changed, reloading.
+INFO 2025-09-07 18:52:35,775 autoreload 33342 8747049152 Watching for file changes with StatReloader
+INFO 2025-09-07 18:52:43,036 basehttp 33342 6171783168 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 18:53:32,887 autoreload 33342 8747049152 /Users/marwanalwali/manus_project/hospital_management_system_v4/hr/models.py changed, reloading.
+INFO 2025-09-07 18:53:33,210 autoreload 33823 8747049152 Watching for file changes with StatReloader
+INFO 2025-09-07 18:53:43,035 basehttp 33823 6158364672 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 18:54:42,988 basehttp 33823 6158364672 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 18:55:42,996 basehttp 33823 6158364672 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 18:56:42,995 basehttp 33823 6158364672 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 18:57:43,002 basehttp 33823 6158364672 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 18:58:14,610 autoreload 33823 8747049152 /Users/marwanalwali/manus_project/hospital_management_system_v4/hr/models.py changed, reloading.
+INFO 2025-09-07 18:58:14,946 autoreload 35826 8747049152 Watching for file changes with StatReloader
+INFO 2025-09-07 19:01:36,616 autoreload 37400 8747049152 Watching for file changes with StatReloader
+WARNING 2025-09-07 19:01:39,903 log 37400 6165229568 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 19:01:39,903 basehttp 37400 6165229568 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-07 19:01:40,024 basehttp 37400 6165229568 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 19:01:49,447 basehttp 37400 6165229568 "GET /en/hr/training-management HTTP/1.1" 200 54669
+WARNING 2025-09-07 19:01:49,464 log 37400 6165229568 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 19:01:49,465 basehttp 37400 6165229568 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-07 19:01:49,534 basehttp 37400 6165229568 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 19:02:05,029 autoreload 37400 8747049152 /Users/marwanalwali/manus_project/hospital_management_system_v4/hr/views.py changed, reloading.
+INFO 2025-09-07 19:02:05,363 autoreload 37565 8747049152 Watching for file changes with StatReloader
+INFO 2025-09-07 19:02:05,952 basehttp 37565 6196097024 "GET /en/hr/training-management HTTP/1.1" 200 94613
+WARNING 2025-09-07 19:02:05,971 log 37565 6196097024 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 19:02:05,971 basehttp 37565 6196097024 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-07 19:02:06,058 basehttp 37565 6196097024 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 19:02:31,038 basehttp 37565 6196097024 "GET /en/hr/training/create/ HTTP/1.1" 200 50385
+WARNING 2025-09-07 19:02:31,056 log 37565 6196097024 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 19:02:31,056 basehttp 37565 6196097024 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-07 19:02:31,137 basehttp 37565 6196097024 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+WARNING 2025-09-07 19:02:35,803 log 37565 6196097024 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 19:02:35,803 basehttp 37565 6196097024 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+WARNING 2025-09-07 19:02:35,812 log 37565 6196097024 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 19:02:35,813 basehttp 37565 6196097024 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-07 19:03:06,065 basehttp 37565 6196097024 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 19:03:56,545 autoreload 37565 8747049152 /Users/marwanalwali/manus_project/hospital_management_system_v4/hr/views.py changed, reloading.
+INFO 2025-09-07 19:03:56,902 autoreload 38419 8747049152 Watching for file changes with StatReloader
+WARNING 2025-09-07 19:03:57,860 log 38419 6159265792 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 19:03:57,861 basehttp 38419 6159265792 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+WARNING 2025-09-07 19:03:57,872 log 38419 6159265792 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 19:03:57,872 basehttp 38419 6159265792 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-07 19:03:59,887 basehttp 38419 6159265792 "GET /en/hr/training-management HTTP/1.1" 200 97400
+WARNING 2025-09-07 19:03:59,901 log 38419 6159265792 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 19:03:59,901 basehttp 38419 6159265792 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-07 19:03:59,985 basehttp 38419 6159265792 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 19:04:02,939 basehttp 38419 6159265792 "GET /en/hr/training-management?page=2 HTTP/1.1" 200 97758
+WARNING 2025-09-07 19:04:02,962 log 38419 6159265792 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 19:04:02,962 basehttp 38419 6159265792 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-07 19:04:03,046 basehttp 38419 6159265792 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 19:04:22,791 basehttp 38419 6159265792 "GET /en/hr/training/ HTTP/1.1" 200 36297
+WARNING 2025-09-07 19:04:22,810 log 38419 6159265792 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 19:04:22,810 basehttp 38419 6159265792 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-07 19:04:22,892 basehttp 38419 6159265792 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 19:04:40,791 autoreload 38419 8747049152 /Users/marwanalwali/manus_project/hospital_management_system_v4/hr/views.py changed, reloading.
+INFO 2025-09-07 19:04:41,117 autoreload 38736 8747049152 Watching for file changes with StatReloader
+WARNING 2025-09-07 19:04:42,402 log 38736 6197555200 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 19:04:42,403 basehttp 38736 6197555200 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+WARNING 2025-09-07 19:04:42,413 log 38736 6197555200 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 19:04:42,414 basehttp 38736 6197555200 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-07 19:04:43,092 basehttp 38736 6197555200 "GET /en/hr/training/ HTTP/1.1" 200 117087
+WARNING 2025-09-07 19:04:43,108 log 38736 6197555200 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 19:04:43,109 basehttp 38736 6197555200 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-07 19:04:43,204 basehttp 38736 6197555200 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 19:05:43,209 basehttp 38736 6197555200 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 19:05:59,216 basehttp 38736 6197555200 "GET /en/hr/training/ HTTP/1.1" 200 117148
+WARNING 2025-09-07 19:05:59,233 log 38736 6197555200 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 19:05:59,233 basehttp 38736 6197555200 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-07 19:05:59,324 basehttp 38736 6197555200 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 19:06:31,125 basehttp 38736 6197555200 "GET /en/hr/training/ HTTP/1.1" 200 117168
+WARNING 2025-09-07 19:06:31,138 log 38736 6197555200 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 19:06:31,138 basehttp 38736 6197555200 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-07 19:06:31,232 basehttp 38736 6197555200 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 19:07:05,391 basehttp 38736 6197555200 "GET /en/hr/training/ HTTP/1.1" 200 117193
+WARNING 2025-09-07 19:07:05,407 log 38736 6197555200 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 19:07:05,407 basehttp 38736 6197555200 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-07 19:07:05,502 basehttp 38736 6197555200 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 19:07:23,355 basehttp 38736 6197555200 "GET /en/hr/training/ HTTP/1.1" 200 117188
+WARNING 2025-09-07 19:07:23,372 log 38736 6197555200 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 19:07:23,372 basehttp 38736 6197555200 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-07 19:07:23,466 basehttp 38736 6197555200 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 19:07:59,729 basehttp 38736 6197555200 "GET /en/hr/training/ HTTP/1.1" 200 117193
+WARNING 2025-09-07 19:07:59,746 log 38736 6197555200 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 19:07:59,746 basehttp 38736 6197555200 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-07 19:07:59,839 basehttp 38736 6197555200 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 19:08:14,555 basehttp 38736 6197555200 "GET /en/hr/training/ HTTP/1.1" 200 117173
+WARNING 2025-09-07 19:08:14,570 log 38736 6197555200 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 19:08:14,570 basehttp 38736 6197555200 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-07 19:08:14,664 basehttp 38736 6197555200 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+WARNING 2025-09-07 19:08:30,306 log 38736 6214381568 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+INFO 2025-09-07 19:08:30,307 basehttp 38736 6197555200 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+WARNING 2025-09-07 19:08:30,307 basehttp 38736 6214381568 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+WARNING 2025-09-07 19:08:30,316 log 38736 6214381568 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 19:08:30,316 basehttp 38736 6214381568 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-07 19:08:31,215 basehttp 38736 6214381568 "GET /en/hr/training-management?page=2 HTTP/1.1" 200 97758
+WARNING 2025-09-07 19:08:31,229 log 38736 6214381568 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 19:08:31,230 basehttp 38736 6214381568 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-07 19:08:31,318 basehttp 38736 6214381568 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 19:08:43,991 basehttp 38736 6214381568 "GET /en/hr/training/986/ HTTP/1.1" 200 28844
+WARNING 2025-09-07 19:08:44,014 log 38736 6214381568 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 19:08:44,014 basehttp 38736 6214381568 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-07 19:08:44,086 basehttp 38736 6214381568 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 19:09:44,092 basehttp 38736 6214381568 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 19:10:44,103 basehttp 38736 6214381568 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 19:11:44,106 basehttp 38736 6214381568 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 19:12:44,111 basehttp 38736 6214381568 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 19:12:54,530 basehttp 38736 6214381568 "GET / HTTP/1.1" 302 0
+INFO 2025-09-07 19:12:54,555 basehttp 38736 6197555200 "GET /en/ HTTP/1.1" 200 49700
+WARNING 2025-09-07 19:12:54,573 log 38736 6197555200 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 19:12:54,573 basehttp 38736 6197555200 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-07 19:12:54,664 basehttp 38736 6197555200 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 19:12:54,674 basehttp 38736 6248034304 "GET /en/htmx/tenant-info/ HTTP/1.1" 200 1043
+INFO 2025-09-07 19:12:54,676 basehttp 38736 6231207936 "GET /en/htmx/system-health/ HTTP/1.1" 200 1356
+INFO 2025-09-07 19:12:54,677 basehttp 38736 6214381568 "GET /en/htmx/dashboard-stats/ HTTP/1.1" 200 2094
+WARNING 2025-09-07 19:13:04,688 log 38736 6214381568 Not Found: /en/core/departments
+WARNING 2025-09-07 19:13:04,689 basehttp 38736 6214381568 "GET /en/core/departments HTTP/1.1" 404 30136
+WARNING 2025-09-07 19:13:04,710 log 38736 6214381568 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 19:13:04,710 basehttp 38736 6214381568 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+WARNING 2025-09-07 19:13:26,185 log 38736 6214381568 Not Found: /en/core/departments
+WARNING 2025-09-07 19:13:26,186 basehttp 38736 6214381568 "GET /en/core/departments HTTP/1.1" 404 30136
+WARNING 2025-09-07 19:13:26,203 log 38736 6214381568 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 19:13:26,203 basehttp 38736 6214381568 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-07 19:13:32,301 basehttp 38736 6214381568 "GET /en/departments HTTP/1.1" 301 0
+INFO 2025-09-07 19:13:32,322 basehttp 38736 6231207936 "GET /en/departments/ HTTP/1.1" 200 134624
+WARNING 2025-09-07 19:13:32,336 log 38736 6231207936 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 19:13:32,336 basehttp 38736 6231207936 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-07 19:13:32,421 basehttp 38736 6231207936 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 19:13:38,966 basehttp 38736 6231207936 "GET /en/departments/12/ HTTP/1.1" 200 38676
+WARNING 2025-09-07 19:13:38,987 log 38736 6231207936 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 19:13:38,987 basehttp 38736 6231207936 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-07 19:13:39,308 basehttp 38736 6231207936 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 19:13:55,079 basehttp 38736 6231207936 "GET /en/inventory/items/?department=12 HTTP/1.1" 200 73409
+WARNING 2025-09-07 19:13:55,094 log 38736 6231207936 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 19:13:55,095 basehttp 38736 6231207936 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-07 19:13:55,191 basehttp 38736 6231207936 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+WARNING 2025-09-07 19:14:06,976 log 38736 6231207936 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 19:14:06,976 basehttp 38736 6231207936 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+WARNING 2025-09-07 19:14:06,988 log 38736 6231207936 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 19:14:06,988 basehttp 38736 6231207936 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-07 19:14:27,071 basehttp 38736 6231207936 "GET /en/hr/departments/12/ HTTP/1.1" 200 35042
+WARNING 2025-09-07 19:14:27,093 log 38736 6231207936 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 19:14:27,093 basehttp 38736 6231207936 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-07 19:14:27,168 basehttp 38736 6231207936 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 19:14:34,406 basehttp 38736 6231207936 "GET /en/hr/departments/ HTTP/1.1" 200 125426
+WARNING 2025-09-07 19:14:34,428 log 38736 6231207936 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 19:14:34,428 basehttp 38736 6231207936 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-07 19:14:34,516 basehttp 38736 6231207936 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 19:15:06,152 basehttp 38736 6231207936 "GET /en/hr/departments/create/ HTTP/1.1" 200 41288
+WARNING 2025-09-07 19:15:06,169 basehttp 38736 6248034304 "GET /static/plugins/select2-bootstrap5-theme/select2-bootstrap5.min.css HTTP/1.1" 404 2104
+WARNING 2025-09-07 19:15:06,174 log 38736 6231207936 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 19:15:06,174 basehttp 38736 6231207936 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-07 19:15:06,248 basehttp 38736 6231207936 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 19:15:58,471 basehttp 38736 6197555200 "GET /en/departments/create/ HTTP/1.1" 200 43115
+WARNING 2025-09-07 19:15:58,493 log 38736 6197555200 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 19:15:58,493 basehttp 38736 6197555200 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-07 19:15:58,576 basehttp 38736 6197555200 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 19:16:23,074 basehttp 38736 6197555200 "GET /en/hr/departments/create/ HTTP/1.1" 200 41288
+WARNING 2025-09-07 19:16:23,090 basehttp 38736 6214381568 "GET /static/plugins/select2-bootstrap5-theme/select2-bootstrap5.min.css HTTP/1.1" 404 2104
+WARNING 2025-09-07 19:16:23,094 log 38736 6197555200 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 19:16:23,094 basehttp 38736 6197555200 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-07 19:16:23,174 basehttp 38736 6197555200 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 19:17:23,199 basehttp 38736 6197555200 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 19:18:23,191 basehttp 38736 6197555200 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 19:19:23,309 basehttp 38736 6197555200 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 19:20:23,323 basehttp 38736 6197555200 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 19:21:23,325 basehttp 38736 6197555200 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 19:22:23,329 basehttp 38736 6197555200 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 19:23:23,331 basehttp 38736 6197555200 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 19:24:23,324 basehttp 38736 6197555200 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 19:25:23,331 basehttp 38736 6197555200 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 20:16:49,289 autoreload 70364 8747049152 Watching for file changes with StatReloader
+INFO 2025-09-07 20:17:02,711 autoreload 70364 8747049152 /Users/marwanalwali/manus_project/hospital_management_system_v4/blood_bank/models.py changed, reloading.
+INFO 2025-09-07 20:17:03,014 autoreload 70456 8747049152 Watching for file changes with StatReloader
+INFO 2025-09-07 20:17:18,406 autoreload 70456 8747049152 /Users/marwanalwali/manus_project/hospital_management_system_v4/core/admin.py changed, reloading.
+INFO 2025-09-07 20:17:18,672 autoreload 70620 8747049152 Watching for file changes with StatReloader
+INFO 2025-09-07 20:17:27,955 autoreload 70620 8747049152 /Users/marwanalwali/manus_project/hospital_management_system_v4/core/admin.py changed, reloading.
+INFO 2025-09-07 20:17:28,275 autoreload 70706 8747049152 Watching for file changes with StatReloader
+INFO 2025-09-07 20:17:39,722 autoreload 70706 8747049152 /Users/marwanalwali/manus_project/hospital_management_system_v4/core/views.py changed, reloading.
+INFO 2025-09-07 20:17:40,062 autoreload 70801 8747049152 Watching for file changes with StatReloader
+INFO 2025-09-07 20:17:48,381 autoreload 70801 8747049152 /Users/marwanalwali/manus_project/hospital_management_system_v4/core/forms.py changed, reloading.
+INFO 2025-09-07 20:17:48,674 autoreload 70896 8747049152 Watching for file changes with StatReloader
+INFO 2025-09-07 20:18:05,260 autoreload 70896 8747049152 /Users/marwanalwali/manus_project/hospital_management_system_v4/core/forms.py changed, reloading.
+INFO 2025-09-07 20:18:05,558 autoreload 70980 8747049152 Watching for file changes with StatReloader
+INFO 2025-09-07 20:19:38,162 autoreload 71715 8747049152 Watching for file changes with StatReloader
+INFO 2025-09-07 20:20:42,235 autoreload 72212 8747049152 Watching for file changes with StatReloader
+INFO 2025-09-07 20:21:00,993 autoreload 72212 8747049152 /Users/marwanalwali/manus_project/hospital_management_system_v4/blood_bank/forms.py changed, reloading.
+INFO 2025-09-07 20:21:01,300 autoreload 72401 8747049152 Watching for file changes with StatReloader
+INFO 2025-09-07 20:22:50,198 autoreload 73233 8747049152 Watching for file changes with StatReloader
+INFO 2025-09-07 20:23:06,046 autoreload 73233 8747049152 /Users/marwanalwali/manus_project/hospital_management_system_v4/quality/forms.py changed, reloading.
+INFO 2025-09-07 20:23:06,357 autoreload 73391 8747049152 Watching for file changes with StatReloader
+INFO 2025-09-07 20:23:16,822 autoreload 73391 8747049152 /Users/marwanalwali/manus_project/hospital_management_system_v4/core/views.py changed, reloading.
+INFO 2025-09-07 20:23:17,128 autoreload 73473 8747049152 Watching for file changes with StatReloader
+INFO 2025-09-07 20:23:22,390 autoreload 73473 8747049152 /Users/marwanalwali/manus_project/hospital_management_system_v4/core/admin.py changed, reloading.
+INFO 2025-09-07 20:23:22,700 autoreload 73486 8747049152 Watching for file changes with StatReloader
+INFO 2025-09-07 20:23:56,461 autoreload 73486 8747049152 /Users/marwanalwali/manus_project/hospital_management_system_v4/core/models.py changed, reloading.
+INFO 2025-09-07 20:23:56,769 autoreload 73801 8747049152 Watching for file changes with StatReloader
+INFO 2025-09-07 20:24:00,929 autoreload 73820 8747049152 Watching for file changes with StatReloader
+INFO 2025-09-07 20:24:15,641 autoreload 73820 8747049152 /Users/marwanalwali/manus_project/hospital_management_system_v4/core/forms.py changed, reloading.
+INFO 2025-09-07 20:24:15,992 autoreload 73904 8747049152 Watching for file changes with StatReloader
+INFO 2025-09-07 20:24:20,396 autoreload 73904 8747049152 /Users/marwanalwali/manus_project/hospital_management_system_v4/blood_bank/forms.py changed, reloading.
+INFO 2025-09-07 20:24:20,713 autoreload 73991 8747049152 Watching for file changes with StatReloader
+INFO 2025-09-07 20:24:40,610 autoreload 74164 8747049152 Watching for file changes with StatReloader
+INFO 2025-09-07 20:25:54,846 autoreload 74745 8747049152 Watching for file changes with StatReloader
+INFO 2025-09-07 20:26:42,932 autoreload 74745 8747049152 /Users/marwanalwali/manus_project/hospital_management_system_v4/core/models.py changed, reloading.
+INFO 2025-09-07 20:26:43,364 autoreload 75052 8747049152 Watching for file changes with StatReloader
+INFO 2025-09-07 20:26:48,819 basehttp 75052 6202585088 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+WARNING 2025-09-07 20:26:49,726 log 75052 6202585088 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 20:26:49,726 basehttp 75052 6202585088 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-07 20:26:51,621 basehttp 75052 6202585088 "GET / HTTP/1.1" 302 0
+INFO 2025-09-07 20:26:51,644 basehttp 75052 6219411456 "GET /en/ HTTP/1.1" 200 49790
+INFO 2025-09-07 20:26:51,735 basehttp 75052 6219411456 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 20:26:51,739 basehttp 75052 6202585088 "GET /en/htmx/dashboard-stats/ HTTP/1.1" 200 2094
+INFO 2025-09-07 20:26:51,745 basehttp 75052 6253064192 "GET /en/htmx/tenant-info/ HTTP/1.1" 200 1043
+INFO 2025-09-07 20:26:51,746 basehttp 75052 6236237824 "GET /en/htmx/system-health/ HTTP/1.1" 200 1356
+WARNING 2025-09-07 20:26:53,943 log 75052 6236237824 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 20:26:53,943 basehttp 75052 6236237824 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+WARNING 2025-09-07 20:26:55,517 log 75052 6236237824 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 20:26:55,518 basehttp 75052 6236237824 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-07 20:26:58,151 basehttp 75052 6236237824 "GET /en/blood-bank HTTP/1.1" 301 0
+INFO 2025-09-07 20:26:58,179 basehttp 75052 6253064192 "GET /en/blood-bank/ HTTP/1.1" 200 121063
+WARNING 2025-09-07 20:26:58,194 log 75052 6253064192 Not Found: /.well-known/appspecific/com.chrome.devtools.json
+WARNING 2025-09-07 20:26:58,194 basehttp 75052 6253064192 "GET /.well-known/appspecific/com.chrome.devtools.json HTTP/1.1" 404 2668
+INFO 2025-09-07 20:26:58,280 basehttp 75052 6253064192 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 20:27:16,483 basehttp 75052 6253064192 "GET /en/blood-bank/units/38/ HTTP/1.1" 200 35788
+INFO 2025-09-07 20:27:16,522 basehttp 75052 6253064192 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 20:27:27,392 basehttp 75052 6253064192 "GET /en/blood-bank/units/38/test/ HTTP/1.1" 200 45659
+INFO 2025-09-07 20:27:27,427 basehttp 75052 6253064192 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 20:27:40,160 basehttp 75052 6253064192 "GET /en/blood-bank/donors/46/ HTTP/1.1" 200 29824
+INFO 2025-09-07 20:27:40,196 basehttp 75052 6253064192 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 20:27:46,387 basehttp 75052 6253064192 "GET /en/blood-bank/donors/46/eligibility/ HTTP/1.1" 200 33976
+INFO 2025-09-07 20:27:46,422 basehttp 75052 6253064192 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 20:28:28,942 basehttp 75052 6253064192 "GET /en/blood-bank/donors/46/eligibility/ HTTP/1.1" 200 33976
+INFO 2025-09-07 20:28:28,979 basehttp 75052 6253064192 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 20:28:31,872 basehttp 75052 6253064192 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 20:28:34,119 basehttp 75052 6253064192 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 20:28:36,679 basehttp 75052 6253064192 "GET /en/blood-bank/units/ HTTP/1.1" 200 88820
+INFO 2025-09-07 20:28:36,725 basehttp 75052 6253064192 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 20:28:41,682 basehttp 75052 6253064192 "GET /en/blood-bank/units/48/ HTTP/1.1" 200 36489
+INFO 2025-09-07 20:28:41,718 basehttp 75052 6253064192 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 20:29:36,734 basehttp 75052 6253064192 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 20:29:48,297 basehttp 75052 6253064192 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+ERROR 2025-09-07 20:30:04,781 log 75052 6253064192 Internal Server Error: /en/hr/
+Traceback (most recent call last):
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/db/backends/utils.py", line 105, in _execute
+ return self.cursor.execute(sql, params)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/db/backends/sqlite3/base.py", line 360, in execute
+ return super().execute(query, params)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+sqlite3.OperationalError: no such column: hr_employee.national_id
+
+The above exception was the direct cause of the following exception:
+
+Traceback (most recent call last):
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/core/handlers/exception.py", line 55, in inner
+ response = get_response(request)
+ ^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/core/handlers/base.py", line 220, in _get_response
+ response = response.render()
+ ^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/response.py", line 114, in render
+ self.content = self.rendered_content
+ ^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/response.py", line 92, in rendered_content
+ return template.render(context, self._request)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/backends/django.py", line 107, in render
+ return self.template.render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 171, in render
+ return self._render(context)
+ ^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 163, in _render
+ return self.nodelist.render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 1016, in render
+ return SafeString("".join([node.render_annotated(context) for node in self]))
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 977, in render_annotated
+ return self.render(context)
+ ^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/loader_tags.py", line 159, in render
+ return compiled_parent._render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 163, in _render
+ return self.nodelist.render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 1016, in render
+ return SafeString("".join([node.render_annotated(context) for node in self]))
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 977, in render_annotated
+ return self.render(context)
+ ^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/loader_tags.py", line 65, in render
+ result = block.nodelist.render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 1016, in render
+ return SafeString("".join([node.render_annotated(context) for node in self]))
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 977, in render_annotated
+ return self.render(context)
+ ^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/defaulttags.py", line 199, in render
+ len_values = len(values)
+ ^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/db/models/query.py", line 366, in __len__
+ self._fetch_all()
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/db/models/query.py", line 1949, in _fetch_all
+ self._result_cache = list(self._iterable_class(self))
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/db/models/query.py", line 91, in __iter__
+ results = compiler.execute_sql(
+ ^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/db/models/sql/compiler.py", line 1623, in execute_sql
+ cursor.execute(sql, params)
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/db/backends/utils.py", line 122, in execute
+ return super().execute(sql, params)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/db/backends/utils.py", line 79, in execute
+ return self._execute_with_wrappers(
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/db/backends/utils.py", line 92, in _execute_with_wrappers
+ return executor(sql, params, many, context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/db/backends/utils.py", line 100, in _execute
+ with self.db.wrap_database_errors:
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/db/utils.py", line 91, in __exit__
+ raise dj_exc_value.with_traceback(traceback) from exc_value
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/db/backends/utils.py", line 105, in _execute
+ return self.cursor.execute(sql, params)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/db/backends/sqlite3/base.py", line 360, in execute
+ return super().execute(query, params)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+django.db.utils.OperationalError: no such column: hr_employee.national_id
+ERROR 2025-09-07 20:30:04,784 basehttp 75052 6253064192 "GET /en/hr/ HTTP/1.1" 500 235599
+ERROR 2025-09-07 20:30:05,673 log 75052 6253064192 Internal Server Error: /en/hr/
+Traceback (most recent call last):
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/db/backends/utils.py", line 105, in _execute
+ return self.cursor.execute(sql, params)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/db/backends/sqlite3/base.py", line 360, in execute
+ return super().execute(query, params)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+sqlite3.OperationalError: no such column: hr_employee.national_id
+
+The above exception was the direct cause of the following exception:
+
+Traceback (most recent call last):
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/core/handlers/exception.py", line 55, in inner
+ response = get_response(request)
+ ^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/core/handlers/base.py", line 220, in _get_response
+ response = response.render()
+ ^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/response.py", line 114, in render
+ self.content = self.rendered_content
+ ^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/response.py", line 92, in rendered_content
+ return template.render(context, self._request)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/backends/django.py", line 107, in render
+ return self.template.render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 171, in render
+ return self._render(context)
+ ^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 163, in _render
+ return self.nodelist.render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 1016, in render
+ return SafeString("".join([node.render_annotated(context) for node in self]))
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 977, in render_annotated
+ return self.render(context)
+ ^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/loader_tags.py", line 159, in render
+ return compiled_parent._render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 163, in _render
+ return self.nodelist.render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 1016, in render
+ return SafeString("".join([node.render_annotated(context) for node in self]))
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 977, in render_annotated
+ return self.render(context)
+ ^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/loader_tags.py", line 65, in render
+ result = block.nodelist.render(context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 1016, in render
+ return SafeString("".join([node.render_annotated(context) for node in self]))
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/base.py", line 977, in render_annotated
+ return self.render(context)
+ ^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/template/defaulttags.py", line 199, in render
+ len_values = len(values)
+ ^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/db/models/query.py", line 366, in __len__
+ self._fetch_all()
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/db/models/query.py", line 1949, in _fetch_all
+ self._result_cache = list(self._iterable_class(self))
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/db/models/query.py", line 91, in __iter__
+ results = compiler.execute_sql(
+ ^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/db/models/sql/compiler.py", line 1623, in execute_sql
+ cursor.execute(sql, params)
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/db/backends/utils.py", line 122, in execute
+ return super().execute(sql, params)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/db/backends/utils.py", line 79, in execute
+ return self._execute_with_wrappers(
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/db/backends/utils.py", line 92, in _execute_with_wrappers
+ return executor(sql, params, many, context)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/db/backends/utils.py", line 100, in _execute
+ with self.db.wrap_database_errors:
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/db/utils.py", line 91, in __exit__
+ raise dj_exc_value.with_traceback(traceback) from exc_value
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/db/backends/utils.py", line 105, in _execute
+ return self.cursor.execute(sql, params)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ File "/Users/marwanalwali/manus_project/hospital_management_system_v4/.venv/lib/python3.12/site-packages/django/db/backends/sqlite3/base.py", line 360, in execute
+ return super().execute(query, params)
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+django.db.utils.OperationalError: no such column: hr_employee.national_id
+ERROR 2025-09-07 20:30:05,674 basehttp 75052 6253064192 "GET /en/hr/ HTTP/1.1" 500 235325
+INFO 2025-09-07 20:32:25,310 autoreload 77623 8747049152 Watching for file changes with StatReloader
+INFO 2025-09-07 20:32:27,794 basehttp 77623 6133952512 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 20:32:27,802 basehttp 77623 6150778880 "GET /en/blood-bank/ HTTP/1.1" 200 121063
+INFO 2025-09-07 20:32:27,852 basehttp 77623 6150778880 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 20:32:29,943 basehttp 77623 6150778880 "GET /en/blood-bank/ HTTP/1.1" 200 121063
+INFO 2025-09-07 20:32:30,000 basehttp 77623 6150778880 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 20:32:34,727 basehttp 77623 6150778880 "GET /en/inpatients/ HTTP/1.1" 200 41725
+INFO 2025-09-07 20:32:34,781 basehttp 77623 6150778880 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 20:32:34,782 basehttp 77623 6133952512 "GET /en/inpatients/stats/ HTTP/1.1" 200 3000
+INFO 2025-09-07 20:32:34,805 basehttp 77623 6167605248 "GET /en/inpatients/bed-grid/ HTTP/1.1" 200 611361
+INFO 2025-09-07 20:32:59,005 basehttp 77623 6167605248 "GET /en/inpatients/beds/ HTTP/1.1" 200 2109891
+INFO 2025-09-07 20:32:59,099 basehttp 77623 6167605248 "GET /static/plugins/dropzone/dist/min/dropzone.min.js HTTP/1.1" 200 114702
+INFO 2025-09-07 20:32:59,124 basehttp 77623 6167605248 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 20:32:59,242 basehttp 77623 6167605248 "GET /en/inpatients/beds/ HTTP/1.1" 200 2109891
+INFO 2025-09-07 20:33:01,667 basehttp 77623 6167605248 "GET /en/inpatients/beds/1619/ HTTP/1.1" 200 31653
+INFO 2025-09-07 20:33:01,702 basehttp 77623 6167605248 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 20:33:25,036 basehttp 77623 6167605248 "GET /en/inpatients/stats/ HTTP/1.1" 200 3000
+INFO 2025-09-07 20:33:34,007 basehttp 77623 6167605248 "GET /en/patients/ HTTP/1.1" 200 139651
+INFO 2025-09-07 20:33:34,059 basehttp 77623 6167605248 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 20:33:34,063 basehttp 77623 6133952512 "GET /en/patients/patient-stats/ HTTP/1.1" 200 12305
+INFO 2025-09-07 20:33:39,047 basehttp 77623 6133952512 "GET /en/patients/patientprofile/39/details/ HTTP/1.1" 200 32460
+INFO 2025-09-07 20:33:39,082 basehttp 77623 6133952512 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 20:34:39,100 basehttp 77623 6133952512 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 20:35:39,416 basehttp 77623 6133952512 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 20:36:40,417 basehttp 77623 6133952512 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 20:37:41,413 basehttp 77623 6133952512 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 20:38:42,412 basehttp 77623 6133952512 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 20:39:43,413 basehttp 77623 6133952512 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 20:40:45,399 basehttp 77623 6133952512 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 20:42:09,408 basehttp 77623 6133952512 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 20:43:09,410 basehttp 77623 6133952512 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 20:45:09,404 basehttp 77623 6133952512 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 20:46:09,397 basehttp 77623 6133952512 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 20:48:09,395 basehttp 77623 6133952512 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 20:49:09,402 basehttp 77623 6133952512 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 20:51:09,395 basehttp 77623 6133952512 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 20:52:09,397 basehttp 77623 6133952512 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 20:53:31,269 basehttp 77623 6133952512 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 20:53:38,787 basehttp 77623 6133952512 "GET /en/patients/insurance-info/39/ HTTP/1.1" 200 36065
+INFO 2025-09-07 20:53:38,809 basehttp 77623 6133952512 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 20:53:51,162 basehttp 77623 6133952512 "GET /en/patients/consent-forms/39/ HTTP/1.1" 200 599
+INFO 2025-09-07 20:53:56,274 basehttp 77623 6133952512 "GET /en/patients/ HTTP/1.1" 200 139651
+INFO 2025-09-07 20:53:56,326 basehttp 77623 6133952512 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 20:53:56,329 basehttp 77623 6150778880 "GET /en/patients/patient-stats/ HTTP/1.1" 200 12305
+INFO 2025-09-07 20:58:11,348 basehttp 77623 6133952512 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 22:29:09,343 basehttp 77623 6133952512 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 22:56:12,284 basehttp 77623 6133952512 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 23:10:41,271 basehttp 77623 6133952512 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 23:11:38,278 basehttp 77623 6133952512 "GET /en/blood-bank/ HTTP/1.1" 200 121063
+INFO 2025-09-07 23:11:38,451 basehttp 77623 6133952512 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 23:12:39,264 basehttp 77623 6133952512 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 23:13:40,266 basehttp 77623 6133952512 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 23:18:49,454 basehttp 77623 6133952512 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 23:19:50,455 basehttp 77623 6133952512 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 23:20:47,478 basehttp 77623 6133952512 "GET /en/blood-bank/ HTTP/1.1" 200 121063
+INFO 2025-09-07 23:20:47,588 basehttp 77623 6133952512 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 23:21:48,460 basehttp 77623 6133952512 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 23:22:49,458 basehttp 77623 6133952512 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 23:23:50,458 basehttp 77623 6133952512 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 23:24:51,454 basehttp 77623 6133952512 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 23:25:48,475 basehttp 77623 6133952512 "GET /en/blood-bank/ HTTP/1.1" 200 121063
+INFO 2025-09-07 23:25:48,575 basehttp 77623 6133952512 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 23:26:49,450 basehttp 77623 6133952512 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 23:27:50,437 basehttp 77623 6133952512 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 23:28:51,448 basehttp 77623 6133952512 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 23:29:52,450 basehttp 77623 6133952512 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 23:30:49,463 basehttp 77623 6133952512 "GET /en/blood-bank/ HTTP/1.1" 200 121063
+INFO 2025-09-07 23:30:49,579 basehttp 77623 6133952512 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 23:31:50,445 basehttp 77623 6133952512 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 23:32:51,454 basehttp 77623 6133952512 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 23:33:52,448 basehttp 77623 6133952512 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 23:34:53,454 basehttp 77623 6133952512 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 23:35:50,472 basehttp 77623 6133952512 "GET /en/blood-bank/ HTTP/1.1" 200 121063
+INFO 2025-09-07 23:35:50,581 basehttp 77623 6133952512 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 23:36:51,456 basehttp 77623 6133952512 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 23:37:52,458 basehttp 77623 6133952512 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 23:38:53,458 basehttp 77623 6133952512 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 23:39:54,460 basehttp 77623 6133952512 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 23:40:51,483 basehttp 77623 6133952512 "GET /en/blood-bank/ HTTP/1.1" 200 121063
+INFO 2025-09-07 23:40:51,576 basehttp 77623 6133952512 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 23:41:52,467 basehttp 77623 6133952512 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 23:42:53,469 basehttp 77623 6133952512 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 23:43:54,465 basehttp 77623 6133952512 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 23:44:55,470 basehttp 77623 6133952512 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 23:45:52,487 basehttp 77623 6133952512 "GET /en/blood-bank/ HTTP/1.1" 200 121063
+INFO 2025-09-07 23:45:52,587 basehttp 77623 6133952512 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 23:46:53,465 basehttp 77623 6133952512 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 23:47:54,470 basehttp 77623 6133952512 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 23:48:55,465 basehttp 77623 6133952512 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 23:49:56,477 basehttp 77623 6133952512 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 23:50:53,495 basehttp 77623 6133952512 "GET /en/blood-bank/ HTTP/1.1" 200 121063
+INFO 2025-09-07 23:50:53,598 basehttp 77623 6133952512 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 23:51:54,481 basehttp 77623 6133952512 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 23:52:55,479 basehttp 77623 6133952512 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 23:53:56,481 basehttp 77623 6133952512 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 23:54:57,475 basehttp 77623 6133952512 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 23:55:54,499 basehttp 77623 6133952512 "GET /en/blood-bank/ HTTP/1.1" 200 121063
+INFO 2025-09-07 23:55:54,616 basehttp 77623 6133952512 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 23:56:55,481 basehttp 77623 6133952512 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 23:57:56,484 basehttp 77623 6133952512 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 23:58:57,482 basehttp 77623 6133952512 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-07 23:59:58,476 basehttp 77623 6133952512 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-08 00:00:55,502 basehttp 77623 6133952512 "GET /en/blood-bank/ HTTP/1.1" 200 121063
+INFO 2025-09-08 00:00:55,612 basehttp 77623 6133952512 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-08 00:01:56,485 basehttp 77623 6133952512 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-08 00:02:57,488 basehttp 77623 6133952512 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-08 00:03:58,489 basehttp 77623 6133952512 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-08 00:04:59,490 basehttp 77623 6133952512 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-08 00:05:56,497 basehttp 77623 6133952512 "GET /en/blood-bank/ HTTP/1.1" 200 121063
+INFO 2025-09-08 00:05:56,590 basehttp 77623 6133952512 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-08 00:06:57,493 basehttp 77623 6133952512 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-08 00:07:58,492 basehttp 77623 6133952512 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-08 00:08:59,495 basehttp 77623 6133952512 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-08 00:10:00,488 basehttp 77623 6133952512 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-08 00:10:57,507 basehttp 77623 6133952512 "GET /en/blood-bank/ HTTP/1.1" 200 121063
+INFO 2025-09-08 00:10:57,573 basehttp 77623 6133952512 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-08 00:11:58,483 basehttp 77623 6133952512 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-08 00:12:59,487 basehttp 77623 6133952512 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-08 00:13:41,726 autoreload 77623 8747049152 /Users/marwanalwali/manus_project/hospital_management_system_v4/accounts/forms.py changed, reloading.
+INFO 2025-09-08 00:13:42,196 autoreload 15542 8747049152 Watching for file changes with StatReloader
+INFO 2025-09-08 00:14:00,567 basehttp 15542 6325039104 "GET /en/htmx/system-notifications/ HTTP/1.1" 200 3840
+INFO 2025-09-08 00:14:29,118 autoreload 15542 8747049152 /Users/marwanalwali/manus_project/hospital_management_system_v4/accounts/views.py changed, reloading.
+INFO 2025-09-08 00:14:29,485 autoreload 15863 8747049152 Watching for file changes with StatReloader
+INFO 2025-09-08 01:20:56,549 autoreload 15863 8747049152 /Users/marwanalwali/manus_project/hospital_management_system_v4/hospital_management/settings.py changed, reloading.
+INFO 2025-09-08 01:20:56,938 autoreload 42555 8747049152 Watching for file changes with StatReloader
+INFO 2025-09-08 02:59:34,343 autoreload 86776 8747049152 Watching for file changes with StatReloader
diff --git a/operating_theatre/__pycache__/flows.cpython-312.pyc b/operating_theatre/__pycache__/flows.cpython-312.pyc
new file mode 100644
index 00000000..9fe415f3
Binary files /dev/null and b/operating_theatre/__pycache__/flows.cpython-312.pyc differ
diff --git a/operating_theatre/flows.py b/operating_theatre/flows.py
new file mode 100644
index 00000000..3221e7e1
--- /dev/null
+++ b/operating_theatre/flows.py
@@ -0,0 +1,689 @@
+# """
+# Viewflow workflows for operating theatre app.
+# Provides surgical scheduling, perioperative workflows, and OR management.
+# """
+#
+# from viewflow import Flow, lock
+# from viewflow.base import this, flow_func
+# from viewflow.contrib import celery
+# from viewflow.decorators import flow_view
+# from viewflow.fields import CharField, ModelField
+# from viewflow.forms import ModelForm
+# from viewflow.views import CreateProcessView, UpdateProcessView
+# from viewflow.models import Process, Task
+# from django.contrib.auth.models import User
+# from django.urls import reverse_lazy
+# from django.utils import timezone
+# from django.db import transaction
+# from django.core.mail import send_mail
+#
+# from .models import SurgicalCase, SurgicalNote, EquipmentUsage, OperatingRoom
+# from .views import (
+# SurgicalSchedulingView, PreoperativeChecklistView, ORSetupView,
+# AnesthesiaInductionView, SurgicalProcedureView, PostoperativeView,
+# SurgicalNoteView, EquipmentTrackingView
+# )
+#
+#
+# class SurgicalCaseProcess(Process):
+# """
+# Viewflow process model for surgical cases
+# """
+# surgical_case = ModelField(SurgicalCase, help_text='Associated surgical case')
+#
+# # Process status tracking
+# case_scheduled = models.BooleanField(default=False)
+# preop_checklist_completed = models.BooleanField(default=False)
+# or_setup_completed = models.BooleanField(default=False)
+# anesthesia_induced = models.BooleanField(default=False)
+# surgery_started = models.BooleanField(default=False)
+# surgery_completed = models.BooleanField(default=False)
+# postop_care_initiated = models.BooleanField(default=False)
+# surgical_note_completed = models.BooleanField(default=False)
+# case_closed = models.BooleanField(default=False)
+#
+# class Meta:
+# verbose_name = 'Surgical Case Process'
+# verbose_name_plural = 'Surgical Case Processes'
+#
+#
+# class SurgicalCaseFlow(Flow):
+# """
+# Surgical Case Workflow
+#
+# This flow manages the complete surgical process from scheduling
+# through postoperative care and documentation.
+# """
+#
+# process_class = SurgicalCaseProcess
+#
+# # Flow definition
+# start = (
+# flow_func(this.start_surgical_case)
+# .Next(this.schedule_surgery)
+# )
+#
+# schedule_surgery = (
+# flow_view(SurgicalSchedulingView)
+# .Permission('operating_theatre.can_schedule_surgery')
+# .Next(this.preoperative_checklist)
+# )
+#
+# preoperative_checklist = (
+# flow_view(PreoperativeChecklistView)
+# .Permission('operating_theatre.can_complete_preop_checklist')
+# .Next(this.setup_or)
+# )
+#
+# setup_or = (
+# flow_view(ORSetupView)
+# .Permission('operating_theatre.can_setup_or')
+# .Next(this.induce_anesthesia)
+# )
+#
+# induce_anesthesia = (
+# flow_view(AnesthesiaInductionView)
+# .Permission('operating_theatre.can_induce_anesthesia')
+# .Next(this.perform_surgery)
+# )
+#
+# perform_surgery = (
+# flow_view(SurgicalProcedureView)
+# .Permission('operating_theatre.can_perform_surgery')
+# .Next(this.postoperative_care)
+# )
+#
+# postoperative_care = (
+# flow_view(PostoperativeView)
+# .Permission('operating_theatre.can_provide_postop_care')
+# .Next(this.parallel_documentation)
+# )
+#
+# parallel_documentation = (
+# flow_func(this.start_parallel_documentation)
+# .Next(this.complete_surgical_note)
+# .Next(this.track_equipment)
+# )
+#
+# complete_surgical_note = (
+# flow_view(SurgicalNoteView)
+# .Permission('operating_theatre.can_complete_surgical_notes')
+# .Next(this.join_documentation)
+# )
+#
+# track_equipment = (
+# flow_view(EquipmentTrackingView)
+# .Permission('operating_theatre.can_track_equipment')
+# .Next(this.join_documentation)
+# )
+#
+# join_documentation = (
+# flow_func(this.join_parallel_documentation)
+# .Next(this.finalize_case)
+# )
+#
+# finalize_case = (
+# flow_func(this.complete_surgical_case)
+# .Next(this.end)
+# )
+#
+# end = flow_func(this.end_surgical_case)
+#
+# # Flow functions
+# def start_surgical_case(self, activation):
+# """Initialize the surgical case process"""
+# process = activation.process
+# surgical_case = process.surgical_case
+#
+# # Update case status
+# surgical_case.status = 'SCHEDULED'
+# surgical_case.save()
+#
+# # Send notification to OR staff
+# self.notify_or_staff(surgical_case)
+#
+# # Check for emergency cases
+# if surgical_case.priority == 'EMERGENCY':
+# self.notify_emergency_surgery(surgical_case)
+#
+# def start_parallel_documentation(self, activation):
+# """Start parallel documentation tasks"""
+# process = activation.process
+#
+# # Create documentation tasks
+# self.create_documentation_tasks(process.surgical_case)
+#
+# def join_parallel_documentation(self, activation):
+# """Wait for all documentation to complete"""
+# process = activation.process
+#
+# # Check if all documentation is completed
+# if (process.surgical_note_completed and
+# self.equipment_tracking_completed(process.surgical_case)):
+#
+# # Proceed to case finalization
+# self.notify_case_ready_for_closure(process.surgical_case)
+#
+# def complete_surgical_case(self, activation):
+# """Finalize the surgical case process"""
+# process = activation.process
+# surgical_case = process.surgical_case
+#
+# # Update case status
+# surgical_case.status = 'COMPLETED'
+# surgical_case.actual_end_time = timezone.now()
+# surgical_case.save()
+#
+# # Update OR status
+# if surgical_case.operating_room:
+# surgical_case.operating_room.status = 'TURNOVER'
+# surgical_case.operating_room.save()
+#
+# # Mark process as completed
+# process.case_closed = True
+# process.save()
+#
+# # Send completion notifications
+# self.notify_case_completion(surgical_case)
+#
+# # Schedule OR cleaning
+# self.schedule_or_cleaning(surgical_case.operating_room)
+#
+# def end_surgical_case(self, activation):
+# """End the surgical case workflow"""
+# process = activation.process
+#
+# # Generate case summary report
+# self.generate_case_summary(process.surgical_case)
+#
+# # Update quality metrics
+# self.update_quality_metrics(process.surgical_case)
+#
+# # Helper methods
+# def notify_or_staff(self, surgical_case):
+# """Notify OR staff of scheduled surgery"""
+# from django.contrib.auth.models import Group
+#
+# or_staff = User.objects.filter(
+# groups__name='OR Staff'
+# )
+#
+# for staff in or_staff:
+# send_mail(
+# subject=f'Surgery Scheduled: {surgical_case.case_number}',
+# message=f'Surgery scheduled for {surgical_case.patient.get_full_name()} on {surgical_case.scheduled_start_time}.',
+# from_email='or@hospital.com',
+# recipient_list=[staff.email],
+# fail_silently=True
+# )
+#
+# def notify_emergency_surgery(self, surgical_case):
+# """Notify of emergency surgery"""
+# emergency_staff = User.objects.filter(
+# groups__name__in=['OR Staff', 'Anesthesiologists', 'Surgeons']
+# )
+#
+# for staff in emergency_staff:
+# send_mail(
+# subject=f'EMERGENCY Surgery: {surgical_case.case_number}',
+# message=f'Emergency surgery required for {surgical_case.patient.get_full_name()}.',
+# from_email='or@hospital.com',
+# recipient_list=[staff.email],
+# fail_silently=True
+# )
+#
+# def create_documentation_tasks(self, surgical_case):
+# """Create documentation tasks"""
+# # This would create tasks in a task management system
+# pass
+#
+# def equipment_tracking_completed(self, surgical_case):
+# """Check if equipment tracking is completed"""
+# # This would check equipment tracking completion
+# return True
+#
+# def notify_case_ready_for_closure(self, surgical_case):
+# """Notify that case is ready for closure"""
+# if surgical_case.primary_surgeon and surgical_case.primary_surgeon.email:
+# send_mail(
+# subject=f'Case Ready for Closure: {surgical_case.case_number}',
+# message=f'All documentation completed for {surgical_case.patient.get_full_name()}.',
+# from_email='or@hospital.com',
+# recipient_list=[surgical_case.primary_surgeon.email],
+# fail_silently=True
+# )
+#
+# def notify_case_completion(self, surgical_case):
+# """Notify relevant staff of case completion"""
+# # Notify recovery room staff
+# recovery_staff = User.objects.filter(
+# groups__name='Recovery Room Staff'
+# )
+#
+# for staff in recovery_staff:
+# send_mail(
+# subject=f'Patient to Recovery: {surgical_case.patient.get_full_name()}',
+# message=f'Patient from OR {surgical_case.operating_room.room_number} coming to recovery.',
+# from_email='or@hospital.com',
+# recipient_list=[staff.email],
+# fail_silently=True
+# )
+#
+# def schedule_or_cleaning(self, operating_room):
+# """Schedule OR cleaning and turnover"""
+# # This would schedule cleaning with housekeeping
+# pass
+#
+# def generate_case_summary(self, surgical_case):
+# """Generate surgical case summary report"""
+# # This would generate a comprehensive case report
+# pass
+#
+# def update_quality_metrics(self, surgical_case):
+# """Update quality and performance metrics"""
+# # This would update OR efficiency and quality metrics
+# pass
+#
+#
+# class ORSchedulingProcess(Process):
+# """
+# Viewflow process model for OR scheduling
+# """
+# scheduling_date = models.DateField(help_text='Date being scheduled')
+#
+# # Process status tracking
+# schedule_reviewed = models.BooleanField(default=False)
+# conflicts_resolved = models.BooleanField(default=False)
+# staff_assigned = models.BooleanField(default=False)
+# equipment_reserved = models.BooleanField(default=False)
+# schedule_finalized = models.BooleanField(default=False)
+#
+# class Meta:
+# verbose_name = 'OR Scheduling Process'
+# verbose_name_plural = 'OR Scheduling Processes'
+#
+#
+# class ORSchedulingFlow(Flow):
+# """
+# Operating Room Scheduling Workflow
+#
+# This flow manages OR scheduling including conflict resolution,
+# staff assignment, and resource allocation.
+# """
+#
+# process_class = ORSchedulingProcess
+#
+# # Flow definition
+# start = (
+# flow_func(this.start_or_scheduling)
+# .Next(this.review_schedule)
+# )
+#
+# review_schedule = (
+# flow_view(ScheduleReviewView)
+# .Permission('operating_theatre.can_review_schedule')
+# .Next(this.resolve_conflicts)
+# )
+#
+# resolve_conflicts = (
+# flow_view(ConflictResolutionView)
+# .Permission('operating_theatre.can_resolve_conflicts')
+# .Next(this.assign_staff)
+# )
+#
+# assign_staff = (
+# flow_view(StaffAssignmentView)
+# .Permission('operating_theatre.can_assign_staff')
+# .Next(this.reserve_equipment)
+# )
+#
+# reserve_equipment = (
+# flow_view(EquipmentReservationView)
+# .Permission('operating_theatre.can_reserve_equipment')
+# .Next(this.finalize_schedule)
+# )
+#
+# finalize_schedule = (
+# flow_func(this.complete_or_scheduling)
+# .Next(this.end)
+# )
+#
+# end = flow_func(this.end_or_scheduling)
+#
+# # Flow functions
+# def start_or_scheduling(self, activation):
+# """Initialize the OR scheduling process"""
+# process = activation.process
+#
+# # Notify scheduling staff
+# self.notify_scheduling_staff(process.scheduling_date)
+#
+# def complete_or_scheduling(self, activation):
+# """Finalize the OR scheduling process"""
+# process = activation.process
+#
+# # Mark schedule as finalized
+# process.schedule_finalized = True
+# process.save()
+#
+# # Send schedule notifications
+# self.send_schedule_notifications(process.scheduling_date)
+#
+# def end_or_scheduling(self, activation):
+# """End the OR scheduling workflow"""
+# process = activation.process
+#
+# # Generate schedule report
+# self.generate_schedule_report(process.scheduling_date)
+#
+# # Helper methods
+# def notify_scheduling_staff(self, scheduling_date):
+# """Notify scheduling staff"""
+# scheduling_staff = User.objects.filter(
+# groups__name='OR Scheduling'
+# )
+#
+# for staff in scheduling_staff:
+# send_mail(
+# subject=f'OR Schedule Review Required: {scheduling_date}',
+# message=f'OR schedule for {scheduling_date} requires review.',
+# from_email='or@hospital.com',
+# recipient_list=[staff.email],
+# fail_silently=True
+# )
+#
+# def send_schedule_notifications(self, scheduling_date):
+# """Send schedule notifications to all staff"""
+# # This would send schedule notifications
+# pass
+#
+# def generate_schedule_report(self, scheduling_date):
+# """Generate OR schedule report"""
+# # This would generate schedule report
+# pass
+#
+#
+# class EquipmentMaintenanceProcess(Process):
+# """
+# Viewflow process model for equipment maintenance
+# """
+# equipment_id = CharField(max_length=50, help_text='Equipment identifier')
+# maintenance_type = CharField(max_length=20, help_text='Type of maintenance')
+#
+# # Process status tracking
+# maintenance_scheduled = models.BooleanField(default=False)
+# equipment_inspected = models.BooleanField(default=False)
+# maintenance_performed = models.BooleanField(default=False)
+# quality_check_completed = models.BooleanField(default=False)
+# equipment_returned = models.BooleanField(default=False)
+#
+# class Meta:
+# verbose_name = 'Equipment Maintenance Process'
+# verbose_name_plural = 'Equipment Maintenance Processes'
+#
+#
+# class EquipmentMaintenanceFlow(Flow):
+# """
+# Equipment Maintenance Workflow
+#
+# This flow manages equipment maintenance including scheduling,
+# inspection, repair, and quality verification.
+# """
+#
+# process_class = EquipmentMaintenanceProcess
+#
+# # Flow definition
+# start = (
+# flow_func(this.start_equipment_maintenance)
+# .Next(this.schedule_maintenance)
+# )
+#
+# schedule_maintenance = (
+# flow_view(MaintenanceSchedulingView)
+# .Permission('operating_theatre.can_schedule_maintenance')
+# .Next(this.inspect_equipment)
+# )
+#
+# inspect_equipment = (
+# flow_view(EquipmentInspectionView)
+# .Permission('operating_theatre.can_inspect_equipment')
+# .Next(this.perform_maintenance)
+# )
+#
+# perform_maintenance = (
+# flow_view(MaintenanceExecutionView)
+# .Permission('operating_theatre.can_perform_maintenance')
+# .Next(this.quality_check)
+# )
+#
+# quality_check = (
+# flow_view(MaintenanceQualityCheckView)
+# .Permission('operating_theatre.can_quality_check_equipment')
+# .Next(this.return_equipment)
+# )
+#
+# return_equipment = (
+# flow_func(this.complete_equipment_maintenance)
+# .Next(this.end)
+# )
+#
+# end = flow_func(this.end_equipment_maintenance)
+#
+# # Flow functions
+# def start_equipment_maintenance(self, activation):
+# """Initialize the equipment maintenance process"""
+# process = activation.process
+#
+# # Notify maintenance staff
+# self.notify_maintenance_staff(process.equipment_id, process.maintenance_type)
+#
+# def complete_equipment_maintenance(self, activation):
+# """Finalize the equipment maintenance process"""
+# process = activation.process
+#
+# # Mark equipment as available
+# self.return_equipment_to_service(process.equipment_id)
+#
+# # Mark process as completed
+# process.equipment_returned = True
+# process.save()
+#
+# def end_equipment_maintenance(self, activation):
+# """End the equipment maintenance workflow"""
+# process = activation.process
+#
+# # Generate maintenance report
+# self.generate_maintenance_report(process.equipment_id)
+#
+# # Helper methods
+# def notify_maintenance_staff(self, equipment_id, maintenance_type):
+# """Notify maintenance staff"""
+# maintenance_staff = User.objects.filter(
+# groups__name='Equipment Maintenance'
+# )
+#
+# for staff in maintenance_staff:
+# send_mail(
+# subject=f'Equipment Maintenance Required: {equipment_id}',
+# message=f'{maintenance_type} maintenance required for equipment {equipment_id}.',
+# from_email='maintenance@hospital.com',
+# recipient_list=[staff.email],
+# fail_silently=True
+# )
+#
+# def return_equipment_to_service(self, equipment_id):
+# """Return equipment to service"""
+# # This would update equipment status
+# pass
+#
+# def generate_maintenance_report(self, equipment_id):
+# """Generate maintenance report"""
+# # This would generate maintenance report
+# pass
+#
+#
+# class SterilizationProcess(Process):
+# """
+# Viewflow process model for instrument sterilization
+# """
+# sterilization_batch = CharField(max_length=50, help_text='Sterilization batch identifier')
+#
+# # Process status tracking
+# instruments_collected = models.BooleanField(default=False)
+# cleaning_completed = models.BooleanField(default=False)
+# packaging_completed = models.BooleanField(default=False)
+# sterilization_completed = models.BooleanField(default=False)
+# quality_verified = models.BooleanField(default=False)
+# instruments_distributed = models.BooleanField(default=False)
+#
+# class Meta:
+# verbose_name = 'Sterilization Process'
+# verbose_name_plural = 'Sterilization Processes'
+#
+#
+# class SterilizationFlow(Flow):
+# """
+# Instrument Sterilization Workflow
+#
+# This flow manages the sterilization process for surgical instruments
+# including cleaning, packaging, sterilization, and quality verification.
+# """
+#
+# process_class = SterilizationProcess
+#
+# # Flow definition
+# start = (
+# flow_func(this.start_sterilization)
+# .Next(this.collect_instruments)
+# )
+#
+# collect_instruments = (
+# flow_view(InstrumentCollectionView)
+# .Permission('operating_theatre.can_collect_instruments')
+# .Next(this.clean_instruments)
+# )
+#
+# clean_instruments = (
+# flow_view(InstrumentCleaningView)
+# .Permission('operating_theatre.can_clean_instruments')
+# .Next(this.package_instruments)
+# )
+#
+# package_instruments = (
+# flow_view(InstrumentPackagingView)
+# .Permission('operating_theatre.can_package_instruments')
+# .Next(this.sterilize_instruments)
+# )
+#
+# sterilize_instruments = (
+# flow_view(SterilizationExecutionView)
+# .Permission('operating_theatre.can_sterilize_instruments')
+# .Next(this.verify_sterilization)
+# )
+#
+# verify_sterilization = (
+# flow_view(SterilizationVerificationView)
+# .Permission('operating_theatre.can_verify_sterilization')
+# .Next(this.distribute_instruments)
+# )
+#
+# distribute_instruments = (
+# flow_func(this.complete_sterilization)
+# .Next(this.end)
+# )
+#
+# end = flow_func(this.end_sterilization)
+#
+# # Flow functions
+# def start_sterilization(self, activation):
+# """Initialize the sterilization process"""
+# process = activation.process
+#
+# # Notify sterilization staff
+# self.notify_sterilization_staff(process.sterilization_batch)
+#
+# def complete_sterilization(self, activation):
+# """Finalize the sterilization process"""
+# process = activation.process
+#
+# # Mark instruments as available
+# self.mark_instruments_available(process.sterilization_batch)
+#
+# # Mark process as completed
+# process.instruments_distributed = True
+# process.save()
+#
+# def end_sterilization(self, activation):
+# """End the sterilization workflow"""
+# process = activation.process
+#
+# # Generate sterilization report
+# self.generate_sterilization_report(process.sterilization_batch)
+#
+# # Helper methods
+# def notify_sterilization_staff(self, batch):
+# """Notify sterilization staff"""
+# sterilization_staff = User.objects.filter(
+# groups__name='Sterilization Staff'
+# )
+#
+# for staff in sterilization_staff:
+# send_mail(
+# subject=f'Sterilization Batch Ready: {batch}',
+# message=f'Sterilization batch {batch} is ready for processing.',
+# from_email='sterilization@hospital.com',
+# recipient_list=[staff.email],
+# fail_silently=True
+# )
+#
+# def mark_instruments_available(self, batch):
+# """Mark instruments as available"""
+# # This would update instrument availability
+# pass
+#
+# def generate_sterilization_report(self, batch):
+# """Generate sterilization report"""
+# # This would generate sterilization report
+# pass
+#
+#
+# # Celery tasks for background processing
+# @celery.job
+# def auto_schedule_or_cleaning(room_id):
+# """Background task to automatically schedule OR cleaning"""
+# try:
+# # This would schedule OR cleaning
+# return True
+# except Exception:
+# return False
+#
+#
+# @celery.job
+# def monitor_case_delays():
+# """Background task to monitor surgical case delays"""
+# try:
+# # This would monitor for delays and send alerts
+# return True
+# except Exception:
+# return False
+#
+#
+# @celery.job
+# def generate_or_utilization_report():
+# """Background task to generate OR utilization report"""
+# try:
+# # This would generate utilization reports
+# return True
+# except Exception:
+# return False
+#
+#
+# @celery.job
+# def auto_assign_or_staff(case_id):
+# """Background task to automatically assign OR staff"""
+# try:
+# # This would auto-assign staff based on availability
+# return True
+# except Exception:
+# return False
+#
diff --git a/patients/__pycache__/flows.cpython-312.pyc b/patients/__pycache__/flows.cpython-312.pyc
new file mode 100644
index 00000000..6bc9bd7f
Binary files /dev/null and b/patients/__pycache__/flows.cpython-312.pyc differ
diff --git a/patients/__pycache__/views.cpython-312.pyc b/patients/__pycache__/views.cpython-312.pyc
index dcddb5e3..9d78f15d 100644
Binary files a/patients/__pycache__/views.cpython-312.pyc and b/patients/__pycache__/views.cpython-312.pyc differ
diff --git a/patients/flows.py b/patients/flows.py
new file mode 100644
index 00000000..b7455331
--- /dev/null
+++ b/patients/flows.py
@@ -0,0 +1,761 @@
+# """
+# Viewflow workflows for patients app.
+# Provides patient registration, consent management, and record management workflows.
+# """
+#
+# from viewflow import Flow, lock
+# from viewflow.base import this, flow_func
+# from viewflow.contrib import celery
+# from viewflow.decorators import flow_view
+# from viewflow.fields import CharField, ModelField
+# from viewflow.forms import ModelForm
+# from viewflow.views import CreateProcessView, UpdateProcessView
+# from viewflow.models import Process, Task
+# from django.contrib.auth.models import User
+# from django.urls import reverse_lazy
+# from django.utils import timezone
+# from django.db import transaction
+# from django.core.mail import send_mail
+#
+# from .models import PatientProfile, ConsentForm, ConsentTemplate, PatientNote
+# from .views import (
+# PatientRegistrationView, IdentityVerificationView, InsuranceVerificationView,
+# ConsentCollectionView, MedicalHistoryView, EmergencyContactView,
+# ConsentPresentationView, ConsentSigningView, ConsentWitnessView,
+# ConsentVerificationView
+# )
+#
+#
+# class PatientRegistrationProcess(Process):
+# """
+# Viewflow process model for patient registration
+# """
+# patient = ModelField(PatientProfile, help_text='Associated patient')
+#
+# # Process status tracking
+# patient_created = models.BooleanField(default=False)
+# identity_verified = models.BooleanField(default=False)
+# insurance_verified = models.BooleanField(default=False)
+# consents_collected = models.BooleanField(default=False)
+# medical_history_collected = models.BooleanField(default=False)
+# emergency_contacts_added = models.BooleanField(default=False)
+# registration_completed = models.BooleanField(default=False)
+#
+# class Meta:
+# verbose_name = 'Patient Registration Process'
+# verbose_name_plural = 'Patient Registration Processes'
+#
+#
+# class PatientRegistrationFlow(Flow):
+# """
+# Patient Registration Workflow
+#
+# This flow manages the complete patient registration process including
+# identity verification, insurance verification, and consent collection.
+# """
+#
+# process_class = PatientRegistrationProcess
+#
+# # Flow definition
+# start = (
+# flow_func(this.start_registration)
+# .Next(this.create_patient_record)
+# )
+#
+# create_patient_record = (
+# flow_view(PatientRegistrationView)
+# .Permission('patients.can_register_patients')
+# .Next(this.verify_identity)
+# )
+#
+# verify_identity = (
+# flow_view(IdentityVerificationView)
+# .Permission('patients.can_verify_identity')
+# .Next(this.verify_insurance)
+# )
+#
+# verify_insurance = (
+# flow_view(InsuranceVerificationView)
+# .Permission('patients.can_verify_insurance')
+# .Next(this.parallel_data_collection)
+# )
+#
+# parallel_data_collection = (
+# flow_func(this.start_parallel_collection)
+# .Next(this.collect_consents)
+# .Next(this.collect_medical_history)
+# .Next(this.collect_emergency_contacts)
+# )
+#
+# collect_consents = (
+# flow_view(ConsentCollectionView)
+# .Permission('patients.can_collect_consents')
+# .Next(this.join_data_collection)
+# )
+#
+# collect_medical_history = (
+# flow_view(MedicalHistoryView)
+# .Permission('patients.can_collect_medical_history')
+# .Next(this.join_data_collection)
+# )
+#
+# collect_emergency_contacts = (
+# flow_view(EmergencyContactView)
+# .Permission('patients.can_collect_emergency_contacts')
+# .Next(this.join_data_collection)
+# )
+#
+# join_data_collection = (
+# flow_func(this.join_parallel_collection)
+# .Next(this.finalize_registration)
+# )
+#
+# finalize_registration = (
+# flow_func(this.complete_registration)
+# .Next(this.end)
+# )
+#
+# end = flow_func(this.end_registration)
+#
+# # Flow functions
+# def start_registration(self, activation):
+# """Initialize the registration process"""
+# process = activation.process
+#
+# # Log registration start
+# self.log_registration_start(process.patient)
+#
+# # Notify registration staff
+# self.notify_registration_staff(process.patient)
+#
+# def start_parallel_collection(self, activation):
+# """Start parallel data collection tasks"""
+# process = activation.process
+#
+# # Create parallel collection tasks
+# self.create_collection_tasks(process.patient)
+#
+# def join_parallel_collection(self, activation):
+# """Wait for all data collection to complete"""
+# process = activation.process
+#
+# # Check if all collection is completed
+# if (process.consents_collected and
+# process.medical_history_collected and
+# process.emergency_contacts_added):
+#
+# # Proceed to finalization
+# self.notify_registration_ready(process.patient)
+#
+# def complete_registration(self, activation):
+# """Finalize the registration process"""
+# process = activation.process
+# patient = process.patient
+#
+# # Update patient status
+# patient.registration_status = 'COMPLETED'
+# patient.save()
+#
+# # Generate MRN if not already assigned
+# if not patient.mrn:
+# patient.mrn = self.generate_mrn()
+# patient.save()
+#
+# # Mark process as completed
+# process.registration_completed = True
+# process.save()
+#
+# # Send completion notifications
+# self.notify_registration_completion(patient)
+#
+# # Create patient chart
+# self.create_patient_chart(patient)
+#
+# def end_registration(self, activation):
+# """End the registration workflow"""
+# process = activation.process
+#
+# # Generate registration summary report
+# self.generate_registration_summary(process.patient)
+#
+# # Update registration metrics
+# self.update_registration_metrics(process.patient)
+#
+# # Helper methods
+# def log_registration_start(self, patient):
+# """Log registration start"""
+# # This would log the registration start
+# pass
+#
+# def notify_registration_staff(self, patient):
+# """Notify registration staff of new patient"""
+# from django.contrib.auth.models import Group
+#
+# registration_staff = User.objects.filter(
+# groups__name='Registration Staff'
+# )
+#
+# for staff in registration_staff:
+# send_mail(
+# subject=f'New Patient Registration: {patient.get_full_name()}',
+# message=f'New patient registration started for {patient.get_full_name()}.',
+# from_email='registration@hospital.com',
+# recipient_list=[staff.email],
+# fail_silently=True
+# )
+#
+# def create_collection_tasks(self, patient):
+# """Create data collection tasks"""
+# # This would create tasks in a task management system
+# pass
+#
+# def notify_registration_ready(self, patient):
+# """Notify that registration is ready for completion"""
+# registration_staff = User.objects.filter(
+# groups__name='Registration Staff'
+# )
+#
+# for staff in registration_staff:
+# send_mail(
+# subject=f'Registration Ready: {patient.get_full_name()}',
+# message=f'Patient registration for {patient.get_full_name()} is ready for completion.',
+# from_email='registration@hospital.com',
+# recipient_list=[staff.email],
+# fail_silently=True
+# )
+#
+# def generate_mrn(self):
+# """Generate unique Medical Record Number"""
+# from django.utils.crypto import get_random_string
+# return f"MRN{timezone.now().strftime('%Y%m%d')}{get_random_string(6, '0123456789')}"
+#
+# def notify_registration_completion(self, patient):
+# """Notify relevant parties of registration completion"""
+# # Notify patient if email available
+# if patient.email:
+# send_mail(
+# subject='Registration Complete',
+# message=f'Welcome {patient.first_name}! Your registration is complete. Your MRN is: {patient.mrn}',
+# from_email='registration@hospital.com',
+# recipient_list=[patient.email],
+# fail_silently=True
+# )
+#
+# def create_patient_chart(self, patient):
+# """Create initial patient chart"""
+# # This would create the initial patient chart
+# pass
+#
+# def generate_registration_summary(self, patient):
+# """Generate registration summary report"""
+# # This would generate a comprehensive registration report
+# pass
+#
+# def update_registration_metrics(self, patient):
+# """Update registration metrics"""
+# # This would update registration performance metrics
+# pass
+#
+#
+# class ConsentManagementProcess(Process):
+# """
+# Viewflow process model for consent management
+# """
+# consent_form = ModelField(ConsentForm, help_text='Associated consent form')
+#
+# # Process status tracking
+# consent_presented = models.BooleanField(default=False)
+# patient_reviewed = models.BooleanField(default=False)
+# questions_answered = models.BooleanField(default=False)
+# consent_signed = models.BooleanField(default=False)
+# witness_signed = models.BooleanField(default=False)
+# consent_verified = models.BooleanField(default=False)
+# consent_filed = models.BooleanField(default=False)
+#
+# class Meta:
+# verbose_name = 'Consent Management Process'
+# verbose_name_plural = 'Consent Management Processes'
+#
+#
+# class ConsentManagementFlow(Flow):
+# """
+# Consent Management Workflow
+#
+# This flow manages the consent collection process including presentation,
+# review, signing, witnessing, and verification.
+# """
+#
+# process_class = ConsentManagementProcess
+#
+# # Flow definition
+# start = (
+# flow_func(this.start_consent_process)
+# .Next(this.present_consent)
+# )
+#
+# present_consent = (
+# flow_view(ConsentPresentationView)
+# .Permission('patients.can_present_consents')
+# .Next(this.patient_review)
+# )
+#
+# patient_review = (
+# flow_view(PatientConsentReviewView)
+# .Permission('patients.can_review_consents')
+# .Next(this.answer_questions)
+# )
+#
+# answer_questions = (
+# flow_view(ConsentQuestionView)
+# .Permission('patients.can_answer_consent_questions')
+# .Next(this.sign_consent)
+# )
+#
+# sign_consent = (
+# flow_view(ConsentSigningView)
+# .Permission('patients.can_sign_consents')
+# .Next(this.witness_consent)
+# )
+#
+# witness_consent = (
+# flow_view(ConsentWitnessView)
+# .Permission('patients.can_witness_consents')
+# .Next(this.verify_consent)
+# )
+#
+# verify_consent = (
+# flow_view(ConsentVerificationView)
+# .Permission('patients.can_verify_consents')
+# .Next(this.file_consent)
+# )
+#
+# file_consent = (
+# flow_func(this.complete_consent_process)
+# .Next(this.end)
+# )
+#
+# end = flow_func(this.end_consent_process)
+#
+# # Flow functions
+# def start_consent_process(self, activation):
+# """Initialize the consent process"""
+# process = activation.process
+# consent = process.consent_form
+#
+# # Update consent status
+# consent.status = 'PENDING'
+# consent.save()
+#
+# # Notify relevant staff
+# self.notify_consent_required(consent)
+#
+# def complete_consent_process(self, activation):
+# """Finalize the consent process"""
+# process = activation.process
+# consent = process.consent_form
+#
+# # Update consent status
+# if consent.is_fully_signed:
+# consent.status = 'SIGNED'
+# else:
+# consent.status = 'DECLINED'
+#
+# consent.save()
+#
+# # Mark process as completed
+# process.consent_filed = True
+# process.save()
+#
+# # Send completion notifications
+# self.notify_consent_completion(consent)
+#
+# # File consent in patient record
+# self.file_consent_in_record(consent)
+#
+# def end_consent_process(self, activation):
+# """End the consent workflow"""
+# process = activation.process
+#
+# # Generate consent summary report
+# self.generate_consent_summary(process.consent_form)
+#
+# # Helper methods
+# def notify_consent_required(self, consent):
+# """Notify staff that consent is required"""
+# nursing_staff = User.objects.filter(
+# groups__name='Nursing Staff'
+# )
+#
+# for staff in nursing_staff:
+# send_mail(
+# subject=f'Consent Required: {consent.patient.get_full_name()}',
+# message=f'Consent form "{consent.template.name}" required for {consent.patient.get_full_name()}.',
+# from_email='consents@hospital.com',
+# recipient_list=[staff.email],
+# fail_silently=True
+# )
+#
+# def notify_consent_completion(self, consent):
+# """Notify relevant parties of consent completion"""
+# # Notify ordering physician if applicable
+# if hasattr(consent, 'ordering_physician') and consent.ordering_physician:
+# if consent.ordering_physician.email:
+# send_mail(
+# subject=f'Consent {consent.status}: {consent.patient.get_full_name()}',
+# message=f'Consent form "{consent.template.name}" has been {consent.status.lower()}.',
+# from_email='consents@hospital.com',
+# recipient_list=[consent.ordering_physician.email],
+# fail_silently=True
+# )
+#
+# def file_consent_in_record(self, consent):
+# """File consent in patient record"""
+# # This would file the consent in the patient's medical record
+# pass
+#
+# def generate_consent_summary(self, consent):
+# """Generate consent summary report"""
+# # This would generate a comprehensive consent report
+# pass
+#
+#
+# class PatientRecordManagementProcess(Process):
+# """
+# Viewflow process model for patient record management
+# """
+# patient_id = CharField(max_length=50, help_text='Patient identifier')
+# record_action = CharField(max_length=20, help_text='Record management action')
+#
+# # Process status tracking
+# record_requested = models.BooleanField(default=False)
+# authorization_verified = models.BooleanField(default=False)
+# record_prepared = models.BooleanField(default=False)
+# quality_checked = models.BooleanField(default=False)
+# record_delivered = models.BooleanField(default=False)
+# delivery_confirmed = models.BooleanField(default=False)
+#
+# class Meta:
+# verbose_name = 'Patient Record Management Process'
+# verbose_name_plural = 'Patient Record Management Processes'
+#
+#
+# class PatientRecordManagementFlow(Flow):
+# """
+# Patient Record Management Workflow
+#
+# This flow manages patient record requests including authorization,
+# preparation, quality checking, and delivery.
+# """
+#
+# process_class = PatientRecordManagementProcess
+#
+# # Flow definition
+# start = (
+# flow_func(this.start_record_management)
+# .Next(this.verify_authorization)
+# )
+#
+# verify_authorization = (
+# flow_view(RecordAuthorizationView)
+# .Permission('patients.can_verify_record_authorization')
+# .Next(this.prepare_record)
+# )
+#
+# prepare_record = (
+# flow_view(RecordPreparationView)
+# .Permission('patients.can_prepare_records')
+# .Next(this.quality_check)
+# )
+#
+# quality_check = (
+# flow_view(RecordQualityCheckView)
+# .Permission('patients.can_quality_check_records')
+# .Next(this.deliver_record)
+# )
+#
+# deliver_record = (
+# flow_view(RecordDeliveryView)
+# .Permission('patients.can_deliver_records')
+# .Next(this.confirm_delivery)
+# )
+#
+# confirm_delivery = (
+# flow_func(this.complete_record_management)
+# .Next(this.end)
+# )
+#
+# end = flow_func(this.end_record_management)
+#
+# # Flow functions
+# def start_record_management(self, activation):
+# """Initialize the record management process"""
+# process = activation.process
+#
+# # Log record request
+# self.log_record_request(process.patient_id, process.record_action)
+#
+# # Notify records staff
+# self.notify_records_staff(process.patient_id, process.record_action)
+#
+# def complete_record_management(self, activation):
+# """Finalize the record management process"""
+# process = activation.process
+#
+# # Mark delivery as confirmed
+# process.delivery_confirmed = True
+# process.save()
+#
+# # Generate delivery confirmation
+# self.generate_delivery_confirmation(process.patient_id, process.record_action)
+#
+# def end_record_management(self, activation):
+# """End the record management workflow"""
+# process = activation.process
+#
+# # Generate record management summary
+# self.generate_record_summary(process.patient_id, process.record_action)
+#
+# # Helper methods
+# def log_record_request(self, patient_id, action):
+# """Log record request"""
+# # This would log the record request
+# pass
+#
+# def notify_records_staff(self, patient_id, action):
+# """Notify records staff"""
+# records_staff = User.objects.filter(
+# groups__name='Medical Records'
+# )
+#
+# for staff in records_staff:
+# send_mail(
+# subject=f'Record Request: {patient_id}',
+# message=f'Record {action} requested for patient {patient_id}.',
+# from_email='records@hospital.com',
+# recipient_list=[staff.email],
+# fail_silently=True
+# )
+#
+# def generate_delivery_confirmation(self, patient_id, action):
+# """Generate delivery confirmation"""
+# # This would generate delivery confirmation
+# pass
+#
+# def generate_record_summary(self, patient_id, action):
+# """Generate record management summary"""
+# # This would generate record management summary
+# pass
+#
+#
+# class PatientTransferProcess(Process):
+# """
+# Viewflow process model for patient transfers between facilities
+# """
+# patient_id = CharField(max_length=50, help_text='Patient identifier')
+# transfer_type = CharField(max_length=20, help_text='Type of transfer')
+#
+# # Process status tracking
+# transfer_requested = models.BooleanField(default=False)
+# receiving_facility_contacted = models.BooleanField(default=False)
+# transfer_approved = models.BooleanField(default=False)
+# records_prepared = models.BooleanField(default=False)
+# transport_arranged = models.BooleanField(default=False)
+# patient_transferred = models.BooleanField(default=False)
+# transfer_confirmed = models.BooleanField(default=False)
+#
+# class Meta:
+# verbose_name = 'Patient Transfer Process'
+# verbose_name_plural = 'Patient Transfer Processes'
+#
+#
+# class PatientTransferFlow(Flow):
+# """
+# Patient Transfer Workflow
+#
+# This flow manages patient transfers between facilities including
+# coordination, approval, preparation, and execution.
+# """
+#
+# process_class = PatientTransferProcess
+#
+# # Flow definition
+# start = (
+# flow_func(this.start_transfer)
+# .Next(this.contact_receiving_facility)
+# )
+#
+# contact_receiving_facility = (
+# flow_view(FacilityContactView)
+# .Permission('patients.can_contact_facilities')
+# .Next(this.approve_transfer)
+# )
+#
+# approve_transfer = (
+# flow_view(TransferApprovalView)
+# .Permission('patients.can_approve_transfers')
+# .Next(this.parallel_preparation)
+# )
+#
+# parallel_preparation = (
+# flow_func(this.start_parallel_preparation)
+# .Next(this.prepare_records)
+# .Next(this.arrange_transport)
+# )
+#
+# prepare_records = (
+# flow_view(TransferRecordPreparationView)
+# .Permission('patients.can_prepare_transfer_records')
+# .Next(this.join_preparation)
+# )
+#
+# arrange_transport = (
+# flow_view(TransportArrangementView)
+# .Permission('patients.can_arrange_transport')
+# .Next(this.join_preparation)
+# )
+#
+# join_preparation = (
+# flow_func(this.join_parallel_preparation)
+# .Next(this.execute_transfer)
+# )
+#
+# execute_transfer = (
+# flow_view(TransferExecutionView)
+# .Permission('patients.can_execute_transfers')
+# .Next(this.confirm_transfer)
+# )
+#
+# confirm_transfer = (
+# flow_func(this.complete_transfer)
+# .Next(this.end)
+# )
+#
+# end = flow_func(this.end_transfer)
+#
+# # Flow functions
+# def start_transfer(self, activation):
+# """Initialize the transfer process"""
+# process = activation.process
+#
+# # Log transfer request
+# self.log_transfer_request(process.patient_id, process.transfer_type)
+#
+# # Notify transfer coordinator
+# self.notify_transfer_coordinator(process.patient_id, process.transfer_type)
+#
+# def start_parallel_preparation(self, activation):
+# """Start parallel preparation tasks"""
+# process = activation.process
+#
+# # Create preparation tasks
+# self.create_preparation_tasks(process.patient_id)
+#
+# def join_parallel_preparation(self, activation):
+# """Wait for all preparation to complete"""
+# process = activation.process
+#
+# # Check if all preparation is completed
+# if process.records_prepared and process.transport_arranged:
+# # Proceed to transfer execution
+# self.notify_transfer_ready(process.patient_id)
+#
+# def complete_transfer(self, activation):
+# """Finalize the transfer process"""
+# process = activation.process
+#
+# # Mark transfer as confirmed
+# process.transfer_confirmed = True
+# process.save()
+#
+# # Send confirmation notifications
+# self.notify_transfer_completion(process.patient_id)
+#
+# def end_transfer(self, activation):
+# """End the transfer workflow"""
+# process = activation.process
+#
+# # Generate transfer summary report
+# self.generate_transfer_summary(process.patient_id, process.transfer_type)
+#
+# # Helper methods
+# def log_transfer_request(self, patient_id, transfer_type):
+# """Log transfer request"""
+# # This would log the transfer request
+# pass
+#
+# def notify_transfer_coordinator(self, patient_id, transfer_type):
+# """Notify transfer coordinator"""
+# coordinators = User.objects.filter(
+# groups__name='Transfer Coordinators'
+# )
+#
+# for coordinator in coordinators:
+# send_mail(
+# subject=f'Patient Transfer Request: {patient_id}',
+# message=f'{transfer_type} transfer requested for patient {patient_id}.',
+# from_email='transfers@hospital.com',
+# recipient_list=[coordinator.email],
+# fail_silently=True
+# )
+#
+# def create_preparation_tasks(self, patient_id):
+# """Create preparation tasks"""
+# # This would create preparation tasks
+# pass
+#
+# def notify_transfer_ready(self, patient_id):
+# """Notify that transfer is ready"""
+# # This would notify that transfer is ready
+# pass
+#
+# def notify_transfer_completion(self, patient_id):
+# """Notify transfer completion"""
+# # This would notify transfer completion
+# pass
+#
+# def generate_transfer_summary(self, patient_id, transfer_type):
+# """Generate transfer summary"""
+# # This would generate transfer summary
+# pass
+#
+#
+# # Celery tasks for background processing
+# @celery.job
+# def auto_verify_insurance(patient_id):
+# """Background task to automatically verify insurance"""
+# try:
+# # This would perform automated insurance verification
+# return True
+# except Exception:
+# return False
+#
+#
+# @celery.job
+# def monitor_consent_expiry():
+# """Background task to monitor consent expiry"""
+# try:
+# # This would monitor expiring consents
+# return True
+# except Exception:
+# return False
+#
+#
+# @celery.job
+# def generate_patient_reports():
+# """Background task to generate patient reports"""
+# try:
+# # This would generate patient reports
+# return True
+# except Exception:
+# return False
+#
+#
+# @celery.job
+# def auto_schedule_follow_ups(patient_id):
+# """Background task to automatically schedule follow-ups"""
+# try:
+# # This would schedule follow-up appointments
+# return True
+# except Exception:
+# return False
+#
diff --git a/patients/views.py b/patients/views.py
index f6983794..7f40554b 100644
--- a/patients/views.py
+++ b/patients/views.py
@@ -1,6 +1,7 @@
"""
Patients app views for hospital management system with comprehensive CRUD operations.
"""
+import uuid
from django.shortcuts import render, get_object_or_404, redirect
from django.contrib.auth.decorators import login_required
@@ -17,6 +18,7 @@ from django.core.paginator import Paginator
from datetime import timedelta, date
from appointments.models import AppointmentRequest
+from core.models import AuditLogEntry
from .models import (
PatientProfile, EmergencyContact, InsuranceInfo,
ConsentTemplate, ConsentForm, PatientNote
@@ -2288,7 +2290,7 @@ class ConsentManagementView(LoginRequiredMixin, PermissionRequiredMixin, Templat
# Get expired/expiring consents
today = timezone.now().date()
- expiry_threshold = today + timezone.timedelta(days=30)
+ expiry_threshold = today + timedelta(days=30)
expiring_consents = ConsentForm.objects.filter(
patient__tenant=self.request.user.tenant,
@@ -2359,14 +2361,10 @@ class ConsentManagementView(LoginRequiredMixin, PermissionRequiredMixin, Templat
return redirect('patients:consent_management')
# Process template form
- template_form = ConsentTemplateForm(
- request.POST,
- user=request.user,
- tenant=request.user.tenant
- )
+ template_form = ConsentTemplateForm
- if template_form.is_valid():
- template = template_form.save()
+ if template_form.is_valid:
+ template = template_form.save
messages.success(
request,
f"Consent template '{template.name}' created successfully."
@@ -2718,7 +2716,14 @@ class ConsentManagementView(LoginRequiredMixin, PermissionRequiredMixin, Templat
# 'patient': patient
# })
#
-#
+
+@login_required
+def insurance_details_api(request, insurance_id):
+ insurance_info = get_object_or_404(InsuranceInfo, pk=insurance_id)
+ return JsonResponse({'insurance_info': insurance_info})
+
+
+
# @login_required
# def insurance_info_list(request, patient_id):
# """
diff --git a/pharmacy/__pycache__/flows.cpython-312.pyc b/pharmacy/__pycache__/flows.cpython-312.pyc
new file mode 100644
index 00000000..c1131893
Binary files /dev/null and b/pharmacy/__pycache__/flows.cpython-312.pyc differ
diff --git a/pharmacy/flows.py b/pharmacy/flows.py
new file mode 100644
index 00000000..a315a720
--- /dev/null
+++ b/pharmacy/flows.py
@@ -0,0 +1,672 @@
+# """
+# Viewflow workflows for pharmacy app.
+# Provides prescription processing, dispensing, and medication administration workflows.
+# """
+#
+# from viewflow import Flow, lock
+# from viewflow.base import this, flow_func
+# from viewflow.contrib import celery
+# from viewflow.decorators import flow_view
+# from viewflow.fields import CharField, ModelField
+# from viewflow.forms import ModelForm
+# from viewflow.views import CreateProcessView, UpdateProcessView
+# from viewflow.models import Process, Task
+# from django.contrib.auth.models import User
+# from django.urls import reverse_lazy
+# from django.utils import timezone
+# from django.db import transaction
+# from django.core.mail import send_mail
+#
+# from .models import Prescription, DispenseRecord, MedicationAdministration, DrugInteraction
+# from .views import (
+# PrescriptionReviewView, DrugInteractionCheckView, InventoryCheckView,
+# MedicationPreparationView, PharmacistVerificationView, DispenseView,
+# PatientCounselingView, MedicationAdministrationView
+# )
+#
+#
+# class PrescriptionProcess(Process):
+# """
+# Viewflow process model for prescription processing
+# """
+# prescription = ModelField(Prescription, help_text='Associated prescription')
+#
+# # Process status tracking
+# prescription_received = models.BooleanField(default=False)
+# clinical_review_completed = models.BooleanField(default=False)
+# drug_interactions_checked = models.BooleanField(default=False)
+# inventory_verified = models.BooleanField(default=False)
+# medication_prepared = models.BooleanField(default=False)
+# pharmacist_verified = models.BooleanField(default=False)
+# patient_counseled = models.BooleanField(default=False)
+# dispensed = models.BooleanField(default=False)
+#
+# class Meta:
+# verbose_name = 'Prescription Process'
+# verbose_name_plural = 'Prescription Processes'
+#
+#
+# class PrescriptionFlow(Flow):
+# """
+# Pharmacy Prescription Processing Workflow
+#
+# This flow manages the complete prescription processing from
+# receipt through dispensing and patient counseling.
+# """
+#
+# process_class = PrescriptionProcess
+#
+# # Flow definition
+# start = (
+# flow_func(this.start_prescription)
+# .Next(this.clinical_review)
+# )
+#
+# clinical_review = (
+# flow_view(PrescriptionReviewView)
+# .Permission('pharmacy.can_review_prescriptions')
+# .Next(this.check_drug_interactions)
+# )
+#
+# check_drug_interactions = (
+# flow_view(DrugInteractionCheckView)
+# .Permission('pharmacy.can_check_interactions')
+# .Next(this.verify_inventory)
+# )
+#
+# verify_inventory = (
+# flow_view(InventoryCheckView)
+# .Permission('pharmacy.can_check_inventory')
+# .Next(this.prepare_medication)
+# )
+#
+# prepare_medication = (
+# flow_view(MedicationPreparationView)
+# .Permission('pharmacy.can_prepare_medications')
+# .Next(this.pharmacist_verification)
+# )
+#
+# pharmacist_verification = (
+# flow_view(PharmacistVerificationView)
+# .Permission('pharmacy.can_verify_prescriptions')
+# .Next(this.dispense_medication)
+# )
+#
+# dispense_medication = (
+# flow_view(DispenseView)
+# .Permission('pharmacy.can_dispense_medications')
+# .Next(this.patient_counseling)
+# )
+#
+# patient_counseling = (
+# flow_view(PatientCounselingView)
+# .Permission('pharmacy.can_counsel_patients')
+# .Next(this.finalize_prescription)
+# )
+#
+# finalize_prescription = (
+# flow_func(this.complete_prescription)
+# .Next(this.end)
+# )
+#
+# end = flow_func(this.end_prescription)
+#
+# # Flow functions
+# def start_prescription(self, activation):
+# """Initialize the prescription process"""
+# process = activation.process
+# prescription = process.prescription
+#
+# # Update prescription status
+# prescription.status = 'RECEIVED'
+# prescription.save()
+#
+# # Send notification to pharmacy staff
+# self.notify_pharmacy_staff(prescription)
+#
+# # Check for priority prescriptions
+# if prescription.priority in ['STAT', 'URGENT']:
+# self.notify_priority_prescription(prescription)
+#
+# def complete_prescription(self, activation):
+# """Finalize the prescription process"""
+# process = activation.process
+# prescription = process.prescription
+#
+# # Update prescription status
+# prescription.status = 'COMPLETED'
+# prescription.save()
+#
+# # Mark process as completed
+# process.dispensed = True
+# process.save()
+#
+# # Send completion notifications
+# self.notify_prescription_completion(prescription)
+#
+# # Schedule follow-up if needed
+# self.schedule_follow_up(prescription)
+#
+# def end_prescription(self, activation):
+# """End the prescription workflow"""
+# process = activation.process
+#
+# # Generate prescription summary report
+# self.generate_prescription_summary(process.prescription)
+#
+# # Helper methods
+# def notify_pharmacy_staff(self, prescription):
+# """Notify pharmacy staff of new prescription"""
+# from django.contrib.auth.models import Group
+#
+# pharmacy_staff = User.objects.filter(
+# groups__name='Pharmacy Staff'
+# )
+#
+# for staff in pharmacy_staff:
+# send_mail(
+# subject=f'New Prescription: {prescription.prescription_number}',
+# message=f'New {prescription.get_priority_display()} prescription for {prescription.patient.get_full_name()}.',
+# from_email='pharmacy@hospital.com',
+# recipient_list=[staff.email],
+# fail_silently=True
+# )
+#
+# def notify_priority_prescription(self, prescription):
+# """Notify of high priority prescription"""
+# pharmacists = User.objects.filter(
+# groups__name='Pharmacists'
+# )
+#
+# for pharmacist in pharmacists:
+# send_mail(
+# subject=f'PRIORITY Prescription: {prescription.prescription_number}',
+# message=f'{prescription.get_priority_display()} prescription requires immediate attention.',
+# from_email='pharmacy@hospital.com',
+# recipient_list=[pharmacist.email],
+# fail_silently=True
+# )
+#
+# def notify_prescription_completion(self, prescription):
+# """Notify prescribing physician of completion"""
+# if prescription.prescribing_physician and prescription.prescribing_physician.email:
+# send_mail(
+# subject=f'Prescription Dispensed: {prescription.prescription_number}',
+# message=f'Prescription has been dispensed for {prescription.patient.get_full_name()}.',
+# from_email='pharmacy@hospital.com',
+# recipient_list=[prescription.prescribing_physician.email],
+# fail_silently=True
+# )
+#
+# def schedule_follow_up(self, prescription):
+# """Schedule follow-up for certain medications"""
+# # This would schedule follow-up based on medication type
+# pass
+#
+# def generate_prescription_summary(self, prescription):
+# """Generate prescription summary report"""
+# # This would generate a comprehensive prescription report
+# pass
+#
+#
+# class MedicationAdministrationProcess(Process):
+# """
+# Viewflow process model for medication administration
+# """
+# administration = ModelField(MedicationAdministration, help_text='Associated administration record')
+#
+# # Process status tracking
+# medication_prepared = models.BooleanField(default=False)
+# patient_identified = models.BooleanField(default=False)
+# medication_verified = models.BooleanField(default=False)
+# administration_completed = models.BooleanField(default=False)
+# response_documented = models.BooleanField(default=False)
+#
+# class Meta:
+# verbose_name = 'Medication Administration Process'
+# verbose_name_plural = 'Medication Administration Processes'
+#
+#
+# class MedicationAdministrationFlow(Flow):
+# """
+# Medication Administration Workflow
+#
+# This flow manages the medication administration process for inpatients
+# following the "5 Rights" of medication administration.
+# """
+#
+# process_class = MedicationAdministrationProcess
+#
+# # Flow definition
+# start = (
+# flow_func(this.start_administration)
+# .Next(this.prepare_medication)
+# )
+#
+# prepare_medication = (
+# flow_view(MedicationPreparationView)
+# .Permission('pharmacy.can_prepare_medications')
+# .Next(this.verify_patient)
+# )
+#
+# verify_patient = (
+# flow_view(PatientIdentificationView)
+# .Permission('pharmacy.can_administer_medications')
+# .Next(this.verify_medication)
+# )
+#
+# verify_medication = (
+# flow_view(MedicationVerificationView)
+# .Permission('pharmacy.can_administer_medications')
+# .Next(this.administer_medication)
+# )
+#
+# administer_medication = (
+# flow_view(MedicationAdministrationView)
+# .Permission('pharmacy.can_administer_medications')
+# .Next(this.document_response)
+# )
+#
+# document_response = (
+# flow_view(AdministrationDocumentationView)
+# .Permission('pharmacy.can_administer_medications')
+# .Next(this.finalize_administration)
+# )
+#
+# finalize_administration = (
+# flow_func(this.complete_administration)
+# .Next(this.end)
+# )
+#
+# end = flow_func(this.end_administration)
+#
+# # Flow functions
+# def start_administration(self, activation):
+# """Initialize the administration process"""
+# process = activation.process
+# administration = process.administration
+#
+# # Update administration status
+# administration.status = 'SCHEDULED'
+# administration.save()
+#
+# # Check for overdue medications
+# if administration.is_overdue:
+# self.notify_overdue_medication(administration)
+#
+# def complete_administration(self, activation):
+# """Finalize the administration process"""
+# process = activation.process
+# administration = process.administration
+#
+# # Update administration status
+# administration.status = 'GIVEN'
+# administration.actual_datetime = timezone.now()
+# administration.save()
+#
+# # Mark process as completed
+# process.administration_completed = True
+# process.response_documented = True
+# process.save()
+#
+# # Check for adverse reactions
+# self.check_adverse_reactions(administration)
+#
+# def end_administration(self, activation):
+# """End the administration workflow"""
+# process = activation.process
+#
+# # Update medication administration record
+# self.update_mar(process.administration)
+#
+# # Helper methods
+# def notify_overdue_medication(self, administration):
+# """Notify nursing staff of overdue medication"""
+# nursing_staff = User.objects.filter(
+# groups__name='Nursing Staff',
+# profile__department=administration.patient.current_ward
+# )
+#
+# for nurse in nursing_staff:
+# send_mail(
+# subject=f'Overdue Medication: {administration.patient.get_full_name()}',
+# message=f'Medication administration is overdue for {administration.prescription.medication.display_name}.',
+# from_email='pharmacy@hospital.com',
+# recipient_list=[nurse.email],
+# fail_silently=True
+# )
+#
+# def check_adverse_reactions(self, administration):
+# """Check for potential adverse reactions"""
+# # This would implement adverse reaction monitoring
+# pass
+#
+# def update_mar(self, administration):
+# """Update Medication Administration Record"""
+# # This would update the MAR system
+# pass
+#
+#
+# class DrugInteractionProcess(Process):
+# """
+# Viewflow process model for drug interaction checking
+# """
+# patient_id = CharField(max_length=50, help_text='Patient identifier')
+# interaction_severity = CharField(max_length=20, help_text='Interaction severity level')
+#
+# # Process status tracking
+# interactions_identified = models.BooleanField(default=False)
+# clinical_review_completed = models.BooleanField(default=False)
+# physician_notified = models.BooleanField(default=False)
+# resolution_documented = models.BooleanField(default=False)
+#
+# class Meta:
+# verbose_name = 'Drug Interaction Process'
+# verbose_name_plural = 'Drug Interaction Processes'
+#
+#
+# class DrugInteractionFlow(Flow):
+# """
+# Drug Interaction Checking Workflow
+#
+# This flow manages drug interaction checking and clinical decision support.
+# """
+#
+# process_class = DrugInteractionProcess
+#
+# # Flow definition
+# start = (
+# flow_func(this.start_interaction_check)
+# .Next(this.identify_interactions)
+# )
+#
+# identify_interactions = (
+# flow_func(this.check_drug_interactions)
+# .Next(this.clinical_review)
+# )
+#
+# clinical_review = (
+# flow_view(InteractionReviewView)
+# .Permission('pharmacy.can_review_interactions')
+# .Next(this.notify_physician)
+# )
+#
+# notify_physician = (
+# flow_func(this.send_physician_notification)
+# .Next(this.document_resolution)
+# )
+#
+# document_resolution = (
+# flow_view(InteractionResolutionView)
+# .Permission('pharmacy.can_resolve_interactions')
+# .Next(this.finalize_interaction_check)
+# )
+#
+# finalize_interaction_check = (
+# flow_func(this.complete_interaction_check)
+# .Next(this.end)
+# )
+#
+# end = flow_func(this.end_interaction_check)
+#
+# # Flow functions
+# def start_interaction_check(self, activation):
+# """Initialize the interaction checking process"""
+# process = activation.process
+#
+# # Log interaction check initiation
+# self.log_interaction_check(process.patient_id)
+#
+# def check_drug_interactions(self, activation):
+# """Check for drug interactions"""
+# process = activation.process
+#
+# # Perform interaction checking logic
+# interactions = self.perform_interaction_check(process.patient_id)
+#
+# if interactions:
+# process.interactions_identified = True
+# process.interaction_severity = self.determine_severity(interactions)
+# process.save()
+#
+# # Alert if severe interactions found
+# if process.interaction_severity in ['MAJOR', 'CONTRAINDICATED']:
+# self.alert_severe_interaction(process.patient_id, interactions)
+#
+# def send_physician_notification(self, activation):
+# """Send notification to prescribing physician"""
+# process = activation.process
+#
+# # Notify physician of interactions
+# self.notify_prescribing_physician(process.patient_id, process.interaction_severity)
+#
+# process.physician_notified = True
+# process.save()
+#
+# def complete_interaction_check(self, activation):
+# """Finalize the interaction checking process"""
+# process = activation.process
+#
+# # Mark process as completed
+# process.resolution_documented = True
+# process.save()
+#
+# def end_interaction_check(self, activation):
+# """End the interaction checking workflow"""
+# process = activation.process
+#
+# # Generate interaction report
+# self.generate_interaction_report(process.patient_id)
+#
+# # Helper methods
+# def log_interaction_check(self, patient_id):
+# """Log interaction check initiation"""
+# # This would log the interaction check
+# pass
+#
+# def perform_interaction_check(self, patient_id):
+# """Perform drug interaction checking"""
+# # This would implement interaction checking logic
+# return []
+#
+# def determine_severity(self, interactions):
+# """Determine overall severity of interactions"""
+# # This would determine the highest severity level
+# return 'MINOR'
+#
+# def alert_severe_interaction(self, patient_id, interactions):
+# """Alert staff of severe interactions"""
+# # This would send immediate alerts
+# pass
+#
+# def notify_prescribing_physician(self, patient_id, severity):
+# """Notify prescribing physician"""
+# # This would send notification to physician
+# pass
+#
+# def generate_interaction_report(self, patient_id):
+# """Generate interaction checking report"""
+# # This would generate a comprehensive interaction report
+# pass
+#
+#
+# class InventoryManagementProcess(Process):
+# """
+# Viewflow process model for pharmacy inventory management
+# """
+# medication_id = CharField(max_length=50, help_text='Medication identifier')
+# action_type = CharField(max_length=20, help_text='Inventory action type')
+#
+# # Process status tracking
+# stock_checked = models.BooleanField(default=False)
+# order_placed = models.BooleanField(default=False)
+# shipment_received = models.BooleanField(default=False)
+# inventory_updated = models.BooleanField(default=False)
+#
+# class Meta:
+# verbose_name = 'Inventory Management Process'
+# verbose_name_plural = 'Inventory Management Processes'
+#
+#
+# class InventoryManagementFlow(Flow):
+# """
+# Pharmacy Inventory Management Workflow
+#
+# This flow manages pharmacy inventory including ordering, receiving, and stock management.
+# """
+#
+# process_class = InventoryManagementProcess
+#
+# # Flow definition
+# start = (
+# flow_func(this.start_inventory_management)
+# .Next(this.check_stock_levels)
+# )
+#
+# check_stock_levels = (
+# flow_func(this.monitor_stock_levels)
+# .Next(this.place_order)
+# )
+#
+# place_order = (
+# flow_view(InventoryOrderView)
+# .Permission('pharmacy.can_manage_inventory')
+# .Next(this.receive_shipment)
+# )
+#
+# receive_shipment = (
+# flow_view(ShipmentReceiptView)
+# .Permission('pharmacy.can_receive_inventory')
+# .Next(this.update_inventory)
+# )
+#
+# update_inventory = (
+# flow_func(this.update_stock_levels)
+# .Next(this.finalize_inventory)
+# )
+#
+# finalize_inventory = (
+# flow_func(this.complete_inventory_management)
+# .Next(this.end)
+# )
+#
+# end = flow_func(this.end_inventory_management)
+#
+# # Flow functions
+# def start_inventory_management(self, activation):
+# """Initialize the inventory management process"""
+# process = activation.process
+#
+# # Log inventory management initiation
+# self.log_inventory_action(process.medication_id, process.action_type)
+#
+# def monitor_stock_levels(self, activation):
+# """Monitor stock levels and identify low stock"""
+# process = activation.process
+#
+# # Check stock levels
+# low_stock_items = self.check_low_stock(process.medication_id)
+#
+# if low_stock_items:
+# process.stock_checked = True
+# process.save()
+#
+# # Alert pharmacy staff of low stock
+# self.alert_low_stock(low_stock_items)
+#
+# def update_stock_levels(self, activation):
+# """Update inventory stock levels"""
+# process = activation.process
+#
+# # Update stock levels in system
+# self.update_medication_stock(process.medication_id)
+#
+# process.inventory_updated = True
+# process.save()
+#
+# def complete_inventory_management(self, activation):
+# """Finalize the inventory management process"""
+# process = activation.process
+#
+# # Generate inventory report
+# self.generate_inventory_report(process.medication_id)
+#
+# def end_inventory_management(self, activation):
+# """End the inventory management workflow"""
+# process = activation.process
+#
+# # Archive inventory transaction
+# self.archive_inventory_transaction(process.medication_id)
+#
+# # Helper methods
+# def log_inventory_action(self, medication_id, action_type):
+# """Log inventory action"""
+# # This would log the inventory action
+# pass
+#
+# def check_low_stock(self, medication_id):
+# """Check for low stock items"""
+# # This would check stock levels
+# return []
+#
+# def alert_low_stock(self, low_stock_items):
+# """Alert staff of low stock"""
+# # This would send low stock alerts
+# pass
+#
+# def update_medication_stock(self, medication_id):
+# """Update medication stock levels"""
+# # This would update stock levels
+# pass
+#
+# def generate_inventory_report(self, medication_id):
+# """Generate inventory report"""
+# # This would generate inventory report
+# pass
+#
+# def archive_inventory_transaction(self, medication_id):
+# """Archive inventory transaction"""
+# # This would archive the transaction
+# pass
+#
+#
+# # Celery tasks for background processing
+# @celery.job
+# def auto_check_drug_interactions(patient_id):
+# """Background task to automatically check drug interactions"""
+# try:
+# # This would perform automated interaction checking
+# return True
+# except Exception:
+# return False
+#
+#
+# @celery.job
+# def monitor_medication_adherence(patient_id):
+# """Background task to monitor medication adherence"""
+# try:
+# # This would monitor patient adherence
+# return True
+# except Exception:
+# return False
+#
+#
+# @celery.job
+# def generate_pharmacy_reports():
+# """Background task to generate daily pharmacy reports"""
+# try:
+# # This would generate daily pharmacy reports
+# return True
+# except Exception:
+# return False
+#
+#
+# @celery.job
+# def auto_reorder_medications():
+# """Background task to automatically reorder low stock medications"""
+# try:
+# # This would automatically reorder medications
+# return True
+# except Exception:
+# return False
+#
diff --git a/pyproject.toml b/pyproject.toml
index 36ef7027..04669975 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -4,45 +4,61 @@ version = "0.1.0"
description = "Add your description here"
requires-python = ">=3.12"
dependencies = [
+ "base>=0.0.0",
"black>=25.1.0",
- "boto3>=1.40.1",
+ "boto3==1.40.25",
+ "botocore==1.40.25",
"celery>=5.5.3",
- "coverage>=7.10.2",
+ "charset-normalizer==3.4.3",
+ "coverage==7.10.6",
"crispy-bootstrap5>=2025.6",
- "django>=5.2.4",
- "django-allauth>=65.10.0",
- "django-anymail>=13.0.1",
+ "cron-descriptor==2.0.6",
+ "decorators>=2.0.7",
+ "django==5.2.6",
+ "django-allauth==65.11.1",
+ "django-anymail==13.1",
"django-celery-beat>=2.8.1",
"django-cors-headers>=4.7.0",
"django-crispy-forms>=2.4",
"django-debug-toolbar>=6.0.0",
"django-extensions>=4.1",
"django-filter>=25.1",
- "django-guardian>=3.0.3",
+ "django-guardian==3.1.0",
"django-health-check>=3.20.0",
"django-otp>=1.6.1",
"django-redis>=6.0.0",
"django-storages>=1.14.6",
- "djangorestframework>=3.16.0",
+ "django-viewflow>=2.2.12",
+ "djangorestframework==3.16.1",
"drf-spectacular>=0.28.0",
"factory-boy>=3.3.3",
+ "faker==37.6.0",
+ "filelock==3.19.1",
"flake8>=7.3.0",
"gunicorn>=23.0.0",
+ "identify==2.6.14",
+ "jsonschema==4.25.1",
"mysqlclient>=2.2.7",
"openpyxl>=3.1.5",
- "pandas>=2.3.1",
+ "pandas==2.3.2",
"pillow>=11.3.0",
- "pre-commit>=4.2.0",
+ "platformdirs==4.4.0",
+ "pre-commit==4.3.0",
+ "prompt-toolkit==3.0.52",
"psutil>=7.0.0",
"psycopg2-binary>=2.9.10",
+ "pytest==8.4.2",
"pytest-django>=4.11.1",
"python-dateutil>=2.9.0.post0",
"python-decouple>=3.8",
"pytz>=2025.2",
- "redis>=6.2.0",
+ "redis==6.4.0",
"reportlab>=4.4.3",
- "requests>=2.32.4",
- "sentry-sdk>=2.34.1",
+ "requests==2.32.5",
+ "rpds-py==0.27.1",
+ "sentry-sdk==2.37.0",
+ "typing-extensions==4.15.0",
"urllib3>=2.5.0",
+ "virtualenv==20.34.0",
"whitenoise>=6.9.0",
]
diff --git a/quality/__pycache__/flows.cpython-312.pyc b/quality/__pycache__/flows.cpython-312.pyc
new file mode 100644
index 00000000..65ccec61
Binary files /dev/null and b/quality/__pycache__/flows.cpython-312.pyc differ
diff --git a/quality/__pycache__/forms.cpython-312.pyc b/quality/__pycache__/forms.cpython-312.pyc
index 71c284bb..9c3df46b 100644
Binary files a/quality/__pycache__/forms.cpython-312.pyc and b/quality/__pycache__/forms.cpython-312.pyc differ
diff --git a/quality/__pycache__/views.cpython-312.pyc b/quality/__pycache__/views.cpython-312.pyc
index abc6d08b..f0a8f47f 100644
Binary files a/quality/__pycache__/views.cpython-312.pyc and b/quality/__pycache__/views.cpython-312.pyc differ
diff --git a/quality/flows.py b/quality/flows.py
new file mode 100644
index 00000000..501e6a13
--- /dev/null
+++ b/quality/flows.py
@@ -0,0 +1,983 @@
+# """
+# Viewflow workflows for quality app.
+# Provides quality assurance, incident management, and improvement workflows.
+# """
+#
+# from viewflow import Flow, lock
+# from viewflow.base import this, flow_func
+# from viewflow.contrib import celery
+# from viewflow.decorators import flow_view
+# from viewflow.fields import CharField, ModelField
+# from viewflow.forms import ModelForm
+# from viewflow.views import CreateProcessView, UpdateProcessView
+# from viewflow.models import Process, Task
+# from django.contrib.auth.models import User
+# from django.urls import reverse_lazy
+# from django.utils import timezone
+# from django.db import transaction
+# from django.core.mail import send_mail
+#
+# from .models import (
+# QualityIndicator, QualityMeasurement, IncidentReport, RiskAssessment,
+# AuditPlan, AuditFinding, ImprovementProject
+# )
+# from .views import (
+# IncidentReportingView, IncidentInvestigationView, RootCauseAnalysisView,
+# CorrectiveActionView, IncidentClosureView, QualityMeasurementView,
+# IndicatorAnalysisView, AuditPlanningView, AuditExecutionView,
+# FindingManagementView, ImprovementProjectView, RiskAssessmentView
+# )
+#
+#
+# class IncidentManagementProcess(Process):
+# """
+# Viewflow process model for incident management
+# """
+# incident_report = ModelField(IncidentReport, help_text='Associated incident report')
+#
+# # Process status tracking
+# incident_reported = models.BooleanField(default=False)
+# initial_assessment_completed = models.BooleanField(default=False)
+# investigation_assigned = models.BooleanField(default=False)
+# investigation_completed = models.BooleanField(default=False)
+# root_cause_identified = models.BooleanField(default=False)
+# corrective_actions_planned = models.BooleanField(default=False)
+# actions_implemented = models.BooleanField(default=False)
+# effectiveness_verified = models.BooleanField(default=False)
+# incident_closed = models.BooleanField(default=False)
+#
+# class Meta:
+# verbose_name = 'Incident Management Process'
+# verbose_name_plural = 'Incident Management Processes'
+#
+#
+# class IncidentManagementFlow(Flow):
+# """
+# Incident Management Workflow
+#
+# This flow manages patient safety incidents from reporting through
+# investigation, corrective action, and closure.
+# """
+#
+# process_class = IncidentManagementProcess
+#
+# # Flow definition
+# start = (
+# flow_func(this.start_incident_management)
+# .Next(this.report_incident)
+# )
+#
+# report_incident = (
+# flow_view(IncidentReportingView)
+# .Permission('quality.can_report_incidents')
+# .Next(this.assess_incident)
+# )
+#
+# assess_incident = (
+# flow_func(this.perform_initial_assessment)
+# .Next(this.assign_investigation)
+# )
+#
+# assign_investigation = (
+# flow_view(InvestigationAssignmentView)
+# .Permission('quality.can_assign_investigations')
+# .Next(this.investigate_incident)
+# )
+#
+# investigate_incident = (
+# flow_view(IncidentInvestigationView)
+# .Permission('quality.can_investigate_incidents')
+# .Next(this.analyze_root_cause)
+# )
+#
+# analyze_root_cause = (
+# flow_view(RootCauseAnalysisView)
+# .Permission('quality.can_analyze_root_causes')
+# .Next(this.plan_corrective_actions)
+# )
+#
+# plan_corrective_actions = (
+# flow_view(CorrectiveActionView)
+# .Permission('quality.can_plan_corrective_actions')
+# .Next(this.implement_actions)
+# )
+#
+# implement_actions = (
+# flow_view(ActionImplementationView)
+# .Permission('quality.can_implement_actions')
+# .Next(this.verify_effectiveness)
+# )
+#
+# verify_effectiveness = (
+# flow_view(EffectivenessVerificationView)
+# .Permission('quality.can_verify_effectiveness')
+# .Next(this.close_incident)
+# )
+#
+# close_incident = (
+# flow_func(this.complete_incident_management)
+# .Next(this.end)
+# )
+#
+# end = flow_func(this.end_incident_management)
+#
+# # Flow functions
+# def start_incident_management(self, activation):
+# """Initialize the incident management process"""
+# process = activation.process
+# incident = process.incident_report
+#
+# # Update incident status
+# incident.status = 'reported'
+# incident.save()
+#
+# # Send immediate notifications
+# self.notify_incident_reported(incident)
+#
+# # Check for high-severity incidents
+# if incident.severity in ['severe_harm', 'death']:
+# self.notify_critical_incident(incident)
+# self.notify_regulatory_bodies(incident)
+#
+# def perform_initial_assessment(self, activation):
+# """Perform initial incident assessment"""
+# process = activation.process
+# incident = process.incident_report
+#
+# # Update incident status
+# incident.status = 'under_investigation'
+# incident.save()
+#
+# # Mark assessment completed
+# process.initial_assessment_completed = True
+# process.save()
+#
+# # Determine investigation priority
+# self.determine_investigation_priority(incident)
+#
+# # Send assessment notifications
+# self.notify_assessment_completed(incident)
+#
+# def complete_incident_management(self, activation):
+# """Finalize the incident management process"""
+# process = activation.process
+# incident = process.incident_report
+#
+# # Update incident status
+# incident.status = 'closed'
+# incident.closed_date = timezone.now()
+# incident.save()
+#
+# # Mark process as completed
+# process.incident_closed = True
+# process.save()
+#
+# # Send completion notifications
+# self.notify_incident_closure(incident)
+#
+# # Update quality metrics
+# self.update_incident_metrics(incident)
+#
+# # Generate lessons learned
+# self.generate_lessons_learned(incident)
+#
+# def end_incident_management(self, activation):
+# """End the incident management workflow"""
+# process = activation.process
+#
+# # Generate incident summary report
+# self.generate_incident_summary(process.incident_report)
+#
+# # Helper methods
+# def notify_incident_reported(self, incident):
+# """Notify quality staff of incident report"""
+# from django.contrib.auth.models import Group
+#
+# quality_staff = User.objects.filter(
+# groups__name='Quality Staff'
+# )
+#
+# for staff in quality_staff:
+# send_mail(
+# subject=f'Incident Reported: {incident.incident_number}',
+# message=f'New {incident.get_severity_display()} incident reported: {incident.title}',
+# from_email='quality@hospital.com',
+# recipient_list=[staff.email],
+# fail_silently=True
+# )
+#
+# def notify_critical_incident(self, incident):
+# """Notify of critical incident"""
+# quality_managers = User.objects.filter(
+# groups__name='Quality Managers'
+# )
+#
+# for manager in quality_managers:
+# send_mail(
+# subject=f'CRITICAL INCIDENT: {incident.incident_number}',
+# message=f'Critical incident requiring immediate attention: {incident.title}',
+# from_email='quality@hospital.com',
+# recipient_list=[manager.email],
+# fail_silently=True
+# )
+#
+# def notify_regulatory_bodies(self, incident):
+# """Notify regulatory bodies if required"""
+# if incident.regulatory_notification:
+# # This would implement regulatory notification logic
+# pass
+#
+# def determine_investigation_priority(self, incident):
+# """Determine investigation priority based on severity"""
+# severity_priority_map = {
+# 'death': 'urgent',
+# 'severe_harm': 'high',
+# 'moderate_harm': 'medium',
+# 'minor_harm': 'low',
+# 'no_harm': 'low'
+# }
+#
+# incident.priority = severity_priority_map.get(incident.severity, 'medium')
+# incident.save()
+#
+# def notify_assessment_completed(self, incident):
+# """Notify assessment completion"""
+# if incident.assigned_to and incident.assigned_to.email:
+# send_mail(
+# subject=f'Investigation Assignment: {incident.incident_number}',
+# message=f'You have been assigned to investigate incident: {incident.title}',
+# from_email='quality@hospital.com',
+# recipient_list=[incident.assigned_to.email],
+# fail_silently=True
+# )
+#
+# def notify_incident_closure(self, incident):
+# """Notify incident closure"""
+# # Notify reporter
+# if incident.reported_by and incident.reported_by.email:
+# send_mail(
+# subject=f'Incident Closed: {incident.incident_number}',
+# message=f'The incident you reported has been investigated and closed.',
+# from_email='quality@hospital.com',
+# recipient_list=[incident.reported_by.email],
+# fail_silently=True
+# )
+#
+# def update_incident_metrics(self, incident):
+# """Update incident quality metrics"""
+# # This would update incident reporting metrics
+# pass
+#
+# def generate_lessons_learned(self, incident):
+# """Generate lessons learned from incident"""
+# # This would create lessons learned documentation
+# pass
+#
+# def generate_incident_summary(self, incident):
+# """Generate incident summary report"""
+# # This would generate comprehensive incident report
+# pass
+#
+#
+# class QualityMonitoringProcess(Process):
+# """
+# Viewflow process model for quality monitoring
+# """
+# quality_indicator = ModelField(QualityIndicator, help_text='Associated quality indicator')
+#
+# # Process status tracking
+# data_collected = models.BooleanField(default=False)
+# measurement_calculated = models.BooleanField(default=False)
+# analysis_completed = models.BooleanField(default=False)
+# trends_identified = models.BooleanField(default=False)
+# actions_recommended = models.BooleanField(default=False)
+# report_generated = models.BooleanField(default=False)
+# monitoring_completed = models.BooleanField(default=False)
+#
+# class Meta:
+# verbose_name = 'Quality Monitoring Process'
+# verbose_name_plural = 'Quality Monitoring Processes'
+#
+#
+# class QualityMonitoringFlow(Flow):
+# """
+# Quality Monitoring Workflow
+#
+# This flow manages quality indicator monitoring including data
+# collection, analysis, and reporting.
+# """
+#
+# process_class = QualityMonitoringProcess
+#
+# # Flow definition
+# start = (
+# flow_func(this.start_quality_monitoring)
+# .Next(this.collect_data)
+# )
+#
+# collect_data = (
+# flow_view(DataCollectionView)
+# .Permission('quality.can_collect_data')
+# .Next(this.calculate_measurement)
+# )
+#
+# calculate_measurement = (
+# flow_view(QualityMeasurementView)
+# .Permission('quality.can_calculate_measurements')
+# .Next(this.analyze_results)
+# )
+#
+# analyze_results = (
+# flow_view(IndicatorAnalysisView)
+# .Permission('quality.can_analyze_indicators')
+# .Next(this.identify_trends)
+# )
+#
+# identify_trends = (
+# flow_func(this.perform_trend_analysis)
+# .Next(this.recommend_actions)
+# )
+#
+# recommend_actions = (
+# flow_view(ActionRecommendationView)
+# .Permission('quality.can_recommend_actions')
+# .Next(this.generate_report)
+# )
+#
+# generate_report = (
+# flow_view(QualityReportView)
+# .Permission('quality.can_generate_reports')
+# .Next(this.complete_monitoring)
+# )
+#
+# complete_monitoring = (
+# flow_func(this.finalize_quality_monitoring)
+# .Next(this.end)
+# )
+#
+# end = flow_func(this.end_quality_monitoring)
+#
+# # Flow functions
+# def start_quality_monitoring(self, activation):
+# """Initialize the quality monitoring process"""
+# process = activation.process
+# indicator = process.quality_indicator
+#
+# # Send notification to responsible staff
+# self.notify_monitoring_due(indicator)
+#
+# def perform_trend_analysis(self, activation):
+# """Perform trend analysis on quality data"""
+# process = activation.process
+# indicator = process.quality_indicator
+#
+# # Analyze trends in measurements
+# trends = self.analyze_indicator_trends(indicator)
+#
+# if trends:
+# process.trends_identified = True
+# process.save()
+#
+# # Alert if concerning trends identified
+# if self.is_concerning_trend(trends):
+# self.alert_quality_managers(indicator, trends)
+#
+# def finalize_quality_monitoring(self, activation):
+# """Finalize the quality monitoring process"""
+# process = activation.process
+# indicator = process.quality_indicator
+#
+# # Mark monitoring as completed
+# process.monitoring_completed = True
+# process.save()
+#
+# # Send completion notifications
+# self.notify_monitoring_completion(indicator)
+#
+# # Schedule next monitoring cycle
+# self.schedule_next_monitoring(indicator)
+#
+# def end_quality_monitoring(self, activation):
+# """End the quality monitoring workflow"""
+# process = activation.process
+#
+# # Generate monitoring summary
+# self.generate_monitoring_summary(process.quality_indicator)
+#
+# # Helper methods
+# def notify_monitoring_due(self, indicator):
+# """Notify responsible staff of monitoring due"""
+# if indicator.responsible_user and indicator.responsible_user.email:
+# send_mail(
+# subject=f'Quality Monitoring Due: {indicator.name}',
+# message=f'Quality indicator monitoring is due for: {indicator.name}',
+# from_email='quality@hospital.com',
+# recipient_list=[indicator.responsible_user.email],
+# fail_silently=True
+# )
+#
+# def analyze_indicator_trends(self, indicator):
+# """Analyze trends in quality indicator"""
+# # This would implement trend analysis logic
+# return {}
+#
+# def is_concerning_trend(self, trends):
+# """Check if trends are concerning"""
+# # This would implement trend evaluation logic
+# return False
+#
+# def alert_quality_managers(self, indicator, trends):
+# """Alert quality managers of concerning trends"""
+# quality_managers = User.objects.filter(
+# groups__name='Quality Managers'
+# )
+#
+# for manager in quality_managers:
+# send_mail(
+# subject=f'Quality Alert: {indicator.name}',
+# message=f'Concerning trend identified in quality indicator: {indicator.name}',
+# from_email='quality@hospital.com',
+# recipient_list=[manager.email],
+# fail_silently=True
+# )
+#
+# def notify_monitoring_completion(self, indicator):
+# """Notify monitoring completion"""
+# # This would notify relevant parties
+# pass
+#
+# def schedule_next_monitoring(self, indicator):
+# """Schedule next monitoring cycle"""
+# # This would schedule the next monitoring cycle
+# pass
+#
+# def generate_monitoring_summary(self, indicator):
+# """Generate monitoring summary"""
+# # This would generate monitoring summary
+# pass
+#
+#
+# class AuditManagementProcess(Process):
+# """
+# Viewflow process model for audit management
+# """
+# audit_plan = ModelField(AuditPlan, help_text='Associated audit plan')
+#
+# # Process status tracking
+# audit_planned = models.BooleanField(default=False)
+# team_assigned = models.BooleanField(default=False)
+# audit_conducted = models.BooleanField(default=False)
+# findings_documented = models.BooleanField(default=False)
+# corrective_actions_planned = models.BooleanField(default=False)
+# actions_implemented = models.BooleanField(default=False)
+# follow_up_completed = models.BooleanField(default=False)
+# audit_closed = models.BooleanField(default=False)
+#
+# class Meta:
+# verbose_name = 'Audit Management Process'
+# verbose_name_plural = 'Audit Management Processes'
+#
+#
+# class AuditManagementFlow(Flow):
+# """
+# Audit Management Workflow
+#
+# This flow manages quality audits from planning through
+# execution, finding management, and closure.
+# """
+#
+# process_class = AuditManagementProcess
+#
+# # Flow definition
+# start = (
+# flow_func(this.start_audit_management)
+# .Next(this.plan_audit)
+# )
+#
+# plan_audit = (
+# flow_view(AuditPlanningView)
+# .Permission('quality.can_plan_audits')
+# .Next(this.assign_team)
+# )
+#
+# assign_team = (
+# flow_view(AuditTeamAssignmentView)
+# .Permission('quality.can_assign_audit_teams')
+# .Next(this.conduct_audit)
+# )
+#
+# conduct_audit = (
+# flow_view(AuditExecutionView)
+# .Permission('quality.can_conduct_audits')
+# .Next(this.document_findings)
+# )
+#
+# document_findings = (
+# flow_view(FindingManagementView)
+# .Permission('quality.can_document_findings')
+# .Next(this.plan_corrective_actions)
+# )
+#
+# plan_corrective_actions = (
+# flow_view(CorrectiveActionPlanningView)
+# .Permission('quality.can_plan_corrective_actions')
+# .Next(this.implement_actions)
+# )
+#
+# implement_actions = (
+# flow_view(ActionImplementationView)
+# .Permission('quality.can_implement_actions')
+# .Next(this.follow_up)
+# )
+#
+# follow_up = (
+# flow_view(AuditFollowUpView)
+# .Permission('quality.can_follow_up_audits')
+# .Next(this.close_audit)
+# )
+#
+# close_audit = (
+# flow_func(this.complete_audit_management)
+# .Next(this.end)
+# )
+#
+# end = flow_func(this.end_audit_management)
+#
+# # Flow functions
+# def start_audit_management(self, activation):
+# """Initialize the audit management process"""
+# process = activation.process
+# audit = process.audit_plan
+#
+# # Update audit status
+# audit.status = 'planned'
+# audit.save()
+#
+# # Send notification to audit team
+# self.notify_audit_planned(audit)
+#
+# def complete_audit_management(self, activation):
+# """Finalize the audit management process"""
+# process = activation.process
+# audit = process.audit_plan
+#
+# # Update audit status
+# audit.status = 'completed'
+# audit.actual_end_date = timezone.now().date()
+# audit.save()
+#
+# # Mark process as completed
+# process.audit_closed = True
+# process.save()
+#
+# # Send completion notifications
+# self.notify_audit_completion(audit)
+#
+# # Update audit metrics
+# self.update_audit_metrics(audit)
+#
+# def end_audit_management(self, activation):
+# """End the audit management workflow"""
+# process = activation.process
+#
+# # Generate audit summary report
+# self.generate_audit_summary(process.audit_plan)
+#
+# # Helper methods
+# def notify_audit_planned(self, audit):
+# """Notify audit team of planned audit"""
+# audit_team = audit.audit_team.all()
+# for member in audit_team:
+# if member.email:
+# send_mail(
+# subject=f'Audit Planned: {audit.title}',
+# message=f'You have been assigned to audit: {audit.title}',
+# from_email='quality@hospital.com',
+# recipient_list=[member.email],
+# fail_silently=True
+# )
+#
+# def notify_audit_completion(self, audit):
+# """Notify audit completion"""
+# # Notify department being audited
+# if audit.department:
+# department_staff = User.objects.filter(
+# department=audit.department
+# )
+# for staff in department_staff:
+# if staff.email:
+# send_mail(
+# subject=f'Audit Completed: {audit.title}',
+# message=f'The audit of your department has been completed.',
+# from_email='quality@hospital.com',
+# recipient_list=[staff.email],
+# fail_silently=True
+# )
+#
+# def update_audit_metrics(self, audit):
+# """Update audit performance metrics"""
+# # This would update audit metrics
+# pass
+#
+# def generate_audit_summary(self, audit):
+# """Generate audit summary report"""
+# # This would generate comprehensive audit report
+# pass
+#
+#
+# class ImprovementProjectProcess(Process):
+# """
+# Viewflow process model for improvement projects
+# """
+# improvement_project = ModelField(ImprovementProject, help_text='Associated improvement project')
+#
+# # Process status tracking
+# project_initiated = models.BooleanField(default=False)
+# team_assembled = models.BooleanField(default=False)
+# baseline_established = models.BooleanField(default=False)
+# improvements_implemented = models.BooleanField(default=False)
+# results_measured = models.BooleanField(default=False)
+# sustainability_ensured = models.BooleanField(default=False)
+# project_completed = models.BooleanField(default=False)
+#
+# class Meta:
+# verbose_name = 'Improvement Project Process'
+# verbose_name_plural = 'Improvement Project Processes'
+#
+#
+# class ImprovementProjectFlow(Flow):
+# """
+# Improvement Project Workflow
+#
+# This flow manages quality improvement projects using
+# structured methodologies like PDSA and Lean.
+# """
+#
+# process_class = ImprovementProjectProcess
+#
+# # Flow definition
+# start = (
+# flow_func(this.start_improvement_project)
+# .Next(this.initiate_project)
+# )
+#
+# initiate_project = (
+# flow_view(ProjectInitiationView)
+# .Permission('quality.can_initiate_projects')
+# .Next(this.assemble_team)
+# )
+#
+# assemble_team = (
+# flow_view(TeamAssemblyView)
+# .Permission('quality.can_assemble_teams')
+# .Next(this.establish_baseline)
+# )
+#
+# establish_baseline = (
+# flow_view(BaselineEstablishmentView)
+# .Permission('quality.can_establish_baseline')
+# .Next(this.implement_improvements)
+# )
+#
+# implement_improvements = (
+# flow_view(ImprovementImplementationView)
+# .Permission('quality.can_implement_improvements')
+# .Next(this.measure_results)
+# )
+#
+# measure_results = (
+# flow_view(ResultsMeasurementView)
+# .Permission('quality.can_measure_results')
+# .Next(this.ensure_sustainability)
+# )
+#
+# ensure_sustainability = (
+# flow_view(SustainabilityView)
+# .Permission('quality.can_ensure_sustainability')
+# .Next(this.complete_project)
+# )
+#
+# complete_project = (
+# flow_func(this.finalize_improvement_project)
+# .Next(this.end)
+# )
+#
+# end = flow_func(this.end_improvement_project)
+#
+# # Flow functions
+# def start_improvement_project(self, activation):
+# """Initialize the improvement project process"""
+# process = activation.process
+# project = process.improvement_project
+#
+# # Update project status
+# project.status = 'planned'
+# project.save()
+#
+# # Send notification to project team
+# self.notify_project_initiated(project)
+#
+# def finalize_improvement_project(self, activation):
+# """Finalize the improvement project process"""
+# process = activation.process
+# project = process.improvement_project
+#
+# # Update project status
+# project.status = 'completed'
+# project.actual_end_date = timezone.now().date()
+# project.save()
+#
+# # Mark process as completed
+# process.project_completed = True
+# process.save()
+#
+# # Send completion notifications
+# self.notify_project_completion(project)
+#
+# # Calculate ROI
+# self.calculate_project_roi(project)
+#
+# def end_improvement_project(self, activation):
+# """End the improvement project workflow"""
+# process = activation.process
+#
+# # Generate project summary report
+# self.generate_project_summary(process.improvement_project)
+#
+# # Helper methods
+# def notify_project_initiated(self, project):
+# """Notify project team of project initiation"""
+# project_team = project.project_team.all()
+# for member in project_team:
+# if member.email:
+# send_mail(
+# subject=f'Improvement Project Started: {project.title}',
+# message=f'You have been assigned to improvement project: {project.title}',
+# from_email='quality@hospital.com',
+# recipient_list=[member.email],
+# fail_silently=True
+# )
+#
+# def notify_project_completion(self, project):
+# """Notify project completion"""
+# # Notify sponsor
+# if project.sponsor and project.sponsor.email:
+# send_mail(
+# subject=f'Project Completed: {project.title}',
+# message=f'The improvement project you sponsored has been completed.',
+# from_email='quality@hospital.com',
+# recipient_list=[project.sponsor.email],
+# fail_silently=True
+# )
+#
+# def calculate_project_roi(self, project):
+# """Calculate project return on investment"""
+# # This would implement ROI calculation logic
+# pass
+#
+# def generate_project_summary(self, project):
+# """Generate project summary report"""
+# # This would generate comprehensive project report
+# pass
+#
+#
+# class RiskManagementProcess(Process):
+# """
+# Viewflow process model for risk management
+# """
+# risk_assessment = ModelField(RiskAssessment, help_text='Associated risk assessment')
+#
+# # Process status tracking
+# risk_identified = models.BooleanField(default=False)
+# risk_assessed = models.BooleanField(default=False)
+# controls_evaluated = models.BooleanField(default=False)
+# mitigation_planned = models.BooleanField(default=False)
+# controls_implemented = models.BooleanField(default=False)
+# effectiveness_monitored = models.BooleanField(default=False)
+# risk_managed = models.BooleanField(default=False)
+#
+# class Meta:
+# verbose_name = 'Risk Management Process'
+# verbose_name_plural = 'Risk Management Processes'
+#
+#
+# class RiskManagementFlow(Flow):
+# """
+# Risk Management Workflow
+#
+# This flow manages risk identification, assessment,
+# mitigation, and monitoring activities.
+# """
+#
+# process_class = RiskManagementProcess
+#
+# # Flow definition
+# start = (
+# flow_func(this.start_risk_management)
+# .Next(this.identify_risk)
+# )
+#
+# identify_risk = (
+# flow_view(RiskIdentificationView)
+# .Permission('quality.can_identify_risks')
+# .Next(this.assess_risk)
+# )
+#
+# assess_risk = (
+# flow_view(RiskAssessmentView)
+# .Permission('quality.can_assess_risks')
+# .Next(this.evaluate_controls)
+# )
+#
+# evaluate_controls = (
+# flow_view(ControlEvaluationView)
+# .Permission('quality.can_evaluate_controls')
+# .Next(this.plan_mitigation)
+# )
+#
+# plan_mitigation = (
+# flow_view(MitigationPlanningView)
+# .Permission('quality.can_plan_mitigation')
+# .Next(this.implement_controls)
+# )
+#
+# implement_controls = (
+# flow_view(ControlImplementationView)
+# .Permission('quality.can_implement_controls')
+# .Next(this.monitor_effectiveness)
+# )
+#
+# monitor_effectiveness = (
+# flow_view(EffectivenessMonitoringView)
+# .Permission('quality.can_monitor_effectiveness')
+# .Next(this.manage_risk)
+# )
+#
+# manage_risk = (
+# flow_func(this.complete_risk_management)
+# .Next(this.end)
+# )
+#
+# end = flow_func(this.end_risk_management)
+#
+# # Flow functions
+# def start_risk_management(self, activation):
+# """Initialize the risk management process"""
+# process = activation.process
+# risk = process.risk_assessment
+#
+# # Update risk status
+# risk.status = 'active'
+# risk.save()
+#
+# # Send notification to risk owner
+# self.notify_risk_identified(risk)
+#
+# def complete_risk_management(self, activation):
+# """Finalize the risk management process"""
+# process = activation.process
+# risk = process.risk_assessment
+#
+# # Update risk status based on residual risk level
+# if risk.residual_risk_level in ['low', 'medium']:
+# risk.status = 'active'
+# else:
+# risk.status = 'under_review'
+#
+# risk.save()
+#
+# # Mark process as completed
+# process.risk_managed = True
+# process.save()
+#
+# # Send completion notifications
+# self.notify_risk_management_completion(risk)
+#
+# # Schedule risk review
+# self.schedule_risk_review(risk)
+#
+# def end_risk_management(self, activation):
+# """End the risk management workflow"""
+# process = activation.process
+#
+# # Generate risk management summary
+# self.generate_risk_summary(process.risk_assessment)
+#
+# # Helper methods
+# def notify_risk_identified(self, risk):
+# """Notify risk owner of identified risk"""
+# if risk.responsible_person and risk.responsible_person.email:
+# send_mail(
+# subject=f'Risk Assignment: {risk.title}',
+# message=f'You have been assigned responsibility for risk: {risk.title}',
+# from_email='quality@hospital.com',
+# recipient_list=[risk.responsible_person.email],
+# fail_silently=True
+# )
+#
+# def notify_risk_management_completion(self, risk):
+# """Notify risk management completion"""
+# # This would notify relevant parties
+# pass
+#
+# def schedule_risk_review(self, risk):
+# """Schedule risk review"""
+# # This would schedule periodic risk reviews
+# pass
+#
+# def generate_risk_summary(self, risk):
+# """Generate risk management summary"""
+# # This would generate risk summary
+# pass
+#
+#
+# # Celery tasks for background processing
+# @celery.job
+# def auto_generate_quality_reports():
+# """Background task to automatically generate quality reports"""
+# try:
+# # This would generate scheduled quality reports
+# return True
+# except Exception:
+# return False
+#
+#
+# @celery.job
+# def monitor_quality_indicators():
+# """Background task to monitor quality indicators"""
+# try:
+# # This would check quality indicators for threshold breaches
+# return True
+# except Exception:
+# return False
+#
+#
+# @celery.job
+# def schedule_audits():
+# """Background task to schedule audits"""
+# try:
+# # This would schedule regular audits
+# return True
+# except Exception:
+# return False
+#
+#
+# @celery.job
+# def track_corrective_actions():
+# """Background task to track corrective action progress"""
+# try:
+# # This would monitor corrective action due dates
+# return True
+# except Exception:
+# return False
+#
+#
+# @celery.job
+# def risk_monitoring():
+# """Background task to monitor risks"""
+# try:
+# # This would monitor risk levels and control effectiveness
+# return True
+# except Exception:
+# return False
+#
diff --git a/radiology/__pycache__/flows.cpython-312.pyc b/radiology/__pycache__/flows.cpython-312.pyc
new file mode 100644
index 00000000..b105d99a
Binary files /dev/null and b/radiology/__pycache__/flows.cpython-312.pyc differ
diff --git a/radiology/flows.py b/radiology/flows.py
new file mode 100644
index 00000000..5a8936c4
--- /dev/null
+++ b/radiology/flows.py
@@ -0,0 +1,746 @@
+# """
+# Viewflow workflows for radiology app.
+# Provides imaging order processing, study execution, and report generation workflows.
+# """
+#
+# from viewflow import Flow, lock
+# from viewflow.base import this, flow_func
+# from viewflow.contrib import celery
+# from viewflow.decorators import flow_view
+# from viewflow.fields import CharField, ModelField
+# from viewflow.forms import ModelForm
+# from viewflow.views import CreateProcessView, UpdateProcessView
+# from viewflow.models import Process, Task
+# from django.contrib.auth.models import User
+# from django.urls import reverse_lazy
+# from django.utils import timezone
+# from django.db import transaction
+# from django.core.mail import send_mail
+#
+# from .models import ImagingOrder, ImagingStudy, RadiologyReport, ReportTemplate
+# from .views import (
+# ImagingOrderView, OrderVerificationView, StudySchedulingView,
+# PatientPreparationView, StudyExecutionView, ImageQualityCheckView,
+# ReportDictationView, ReportTranscriptionView, ReportVerificationView,
+# CriticalFindingNotificationView
+# )
+#
+#
+# class ImagingOrderProcess(Process):
+# """
+# Viewflow process model for imaging orders
+# """
+# imaging_order = ModelField(ImagingOrder, help_text='Associated imaging order')
+#
+# # Process status tracking
+# order_received = models.BooleanField(default=False)
+# order_verified = models.BooleanField(default=False)
+# study_scheduled = models.BooleanField(default=False)
+# patient_prepared = models.BooleanField(default=False)
+# study_completed = models.BooleanField(default=False)
+# images_reviewed = models.BooleanField(default=False)
+# report_dictated = models.BooleanField(default=False)
+# report_finalized = models.BooleanField(default=False)
+# results_communicated = models.BooleanField(default=False)
+#
+# class Meta:
+# verbose_name = 'Imaging Order Process'
+# verbose_name_plural = 'Imaging Order Processes'
+#
+#
+# class ImagingOrderFlow(Flow):
+# """
+# Imaging Order Workflow
+#
+# This flow manages the complete imaging process from order receipt
+# through study execution and report delivery.
+# """
+#
+# process_class = ImagingOrderProcess
+#
+# # Flow definition
+# start = (
+# flow_func(this.start_imaging_order)
+# .Next(this.receive_order)
+# )
+#
+# receive_order = (
+# flow_view(ImagingOrderView)
+# .Permission('radiology.can_receive_orders')
+# .Next(this.verify_order)
+# )
+#
+# verify_order = (
+# flow_view(OrderVerificationView)
+# .Permission('radiology.can_verify_orders')
+# .Next(this.schedule_study)
+# )
+#
+# schedule_study = (
+# flow_view(StudySchedulingView)
+# .Permission('radiology.can_schedule_studies')
+# .Next(this.prepare_patient)
+# )
+#
+# prepare_patient = (
+# flow_view(PatientPreparationView)
+# .Permission('radiology.can_prepare_patients')
+# .Next(this.execute_study)
+# )
+#
+# execute_study = (
+# flow_view(StudyExecutionView)
+# .Permission('radiology.can_execute_studies')
+# .Next(this.review_images)
+# )
+#
+# review_images = (
+# flow_view(ImageQualityCheckView)
+# .Permission('radiology.can_review_images')
+# .Next(this.dictate_report)
+# )
+#
+# dictate_report = (
+# flow_view(ReportDictationView)
+# .Permission('radiology.can_dictate_reports')
+# .Next(this.transcribe_report)
+# )
+#
+# transcribe_report = (
+# flow_view(ReportTranscriptionView)
+# .Permission('radiology.can_transcribe_reports')
+# .Next(this.verify_report)
+# )
+#
+# verify_report = (
+# flow_view(ReportVerificationView)
+# .Permission('radiology.can_verify_reports')
+# .Next(this.check_critical_findings)
+# )
+#
+# check_critical_findings = (
+# flow_func(this.assess_critical_findings)
+# .Next(this.finalize_report)
+# )
+#
+# finalize_report = (
+# flow_func(this.complete_imaging_order)
+# .Next(this.end)
+# )
+#
+# end = flow_func(this.end_imaging_order)
+#
+# # Flow functions
+# def start_imaging_order(self, activation):
+# """Initialize the imaging order process"""
+# process = activation.process
+# order = process.imaging_order
+#
+# # Update order status
+# order.status = 'RECEIVED'
+# order.save()
+#
+# # Send notification to radiology staff
+# self.notify_radiology_staff(order)
+#
+# # Check for STAT orders
+# if order.priority in ['STAT', 'EMERGENCY']:
+# self.notify_stat_order(order)
+#
+# def assess_critical_findings(self, activation):
+# """Check for critical findings and handle notifications"""
+# process = activation.process
+# order = process.imaging_order
+#
+# # Get the associated report
+# try:
+# report = RadiologyReport.objects.get(study__imaging_order=order)
+#
+# if report.critical_finding:
+# # Handle critical finding notification
+# self.handle_critical_finding(report)
+#
+# # Mark as critical communicated
+# report.critical_communicated = True
+# report.critical_communicated_datetime = timezone.now()
+# report.save()
+# except RadiologyReport.DoesNotExist:
+# pass
+#
+# def complete_imaging_order(self, activation):
+# """Finalize the imaging order process"""
+# process = activation.process
+# order = process.imaging_order
+#
+# # Update order status
+# order.status = 'COMPLETED'
+# order.completion_datetime = timezone.now()
+# order.save()
+#
+# # Mark process as completed
+# process.results_communicated = True
+# process.save()
+#
+# # Send completion notifications
+# self.notify_order_completion(order)
+#
+# # Update quality metrics
+# self.update_quality_metrics(order)
+#
+# def end_imaging_order(self, activation):
+# """End the imaging order workflow"""
+# process = activation.process
+#
+# # Generate order summary report
+# self.generate_order_summary(process.imaging_order)
+#
+# # Helper methods
+# def notify_radiology_staff(self, order):
+# """Notify radiology staff of new order"""
+# from django.contrib.auth.models import Group
+#
+# radiology_staff = User.objects.filter(
+# groups__name='Radiology Staff'
+# )
+#
+# for staff in radiology_staff:
+# send_mail(
+# subject=f'New Imaging Order: {order.order_number}',
+# message=f'New {order.get_priority_display()} imaging order for {order.patient.get_full_name()}.',
+# from_email='radiology@hospital.com',
+# recipient_list=[staff.email],
+# fail_silently=True
+# )
+#
+# def notify_stat_order(self, order):
+# """Notify of STAT imaging order"""
+# radiologists = User.objects.filter(
+# groups__name='Radiologists'
+# )
+#
+# for radiologist in radiologists:
+# send_mail(
+# subject=f'STAT Imaging Order: {order.order_number}',
+# message=f'{order.get_priority_display()} imaging order requires immediate attention.',
+# from_email='radiology@hospital.com',
+# recipient_list=[radiologist.email],
+# fail_silently=True
+# )
+#
+# def handle_critical_finding(self, report):
+# """Handle critical finding notification"""
+# # Notify ordering physician immediately
+# if report.study.referring_physician and report.study.referring_physician.email:
+# send_mail(
+# subject=f'CRITICAL FINDING: {report.study.accession_number}',
+# message=f'Critical finding identified in imaging study. Please review immediately.',
+# from_email='radiology@hospital.com',
+# recipient_list=[report.study.referring_physician.email],
+# fail_silently=True
+# )
+#
+# # Notify radiology supervisor
+# supervisors = User.objects.filter(
+# groups__name='Radiology Supervisors'
+# )
+#
+# for supervisor in supervisors:
+# send_mail(
+# subject=f'Critical Finding Communicated: {report.study.accession_number}',
+# message=f'Critical finding has been communicated for study {report.study.accession_number}.',
+# from_email='radiology@hospital.com',
+# recipient_list=[supervisor.email],
+# fail_silently=True
+# )
+#
+# def notify_order_completion(self, order):
+# """Notify ordering physician of completed study"""
+# if order.ordering_provider and order.ordering_provider.email:
+# send_mail(
+# subject=f'Imaging Results Available: {order.order_number}',
+# message=f'Imaging results are now available for {order.patient.get_full_name()}.',
+# from_email='radiology@hospital.com',
+# recipient_list=[order.ordering_provider.email],
+# fail_silently=True
+# )
+#
+# def update_quality_metrics(self, order):
+# """Update radiology quality metrics"""
+# # This would update quality and performance metrics
+# pass
+#
+# def generate_order_summary(self, order):
+# """Generate imaging order summary report"""
+# # This would generate a comprehensive order report
+# pass
+#
+#
+# class RadiologyReportProcess(Process):
+# """
+# Viewflow process model for radiology reports
+# """
+# radiology_report = ModelField(RadiologyReport, help_text='Associated radiology report')
+#
+# # Process status tracking
+# report_initiated = models.BooleanField(default=False)
+# preliminary_read = models.BooleanField(default=False)
+# report_dictated = models.BooleanField(default=False)
+# report_transcribed = models.BooleanField(default=False)
+# report_reviewed = models.BooleanField(default=False)
+# report_signed = models.BooleanField(default=False)
+# report_distributed = models.BooleanField(default=False)
+#
+# class Meta:
+# verbose_name = 'Radiology Report Process'
+# verbose_name_plural = 'Radiology Report Processes'
+#
+#
+# class RadiologyReportFlow(Flow):
+# """
+# Radiology Report Workflow
+#
+# This flow manages the radiology reporting process from initial
+# interpretation through final report distribution.
+# """
+#
+# process_class = RadiologyReportProcess
+#
+# # Flow definition
+# start = (
+# flow_func(this.start_report)
+# .Next(this.preliminary_interpretation)
+# )
+#
+# preliminary_interpretation = (
+# flow_view(PreliminaryInterpretationView)
+# .Permission('radiology.can_preliminary_interpret')
+# .Next(this.dictate_report)
+# )
+#
+# dictate_report = (
+# flow_view(ReportDictationView)
+# .Permission('radiology.can_dictate_reports')
+# .Next(this.transcribe_report)
+# )
+#
+# transcribe_report = (
+# flow_view(ReportTranscriptionView)
+# .Permission('radiology.can_transcribe_reports')
+# .Next(this.review_report)
+# )
+#
+# review_report = (
+# flow_view(ReportReviewView)
+# .Permission('radiology.can_review_reports')
+# .Next(this.sign_report)
+# )
+#
+# sign_report = (
+# flow_view(ReportSigningView)
+# .Permission('radiology.can_sign_reports')
+# .Next(this.distribute_report)
+# )
+#
+# distribute_report = (
+# flow_func(this.complete_report)
+# .Next(this.end)
+# )
+#
+# end = flow_func(this.end_report)
+#
+# # Flow functions
+# def start_report(self, activation):
+# """Initialize the report process"""
+# process = activation.process
+# report = process.radiology_report
+#
+# # Update report status
+# report.status = 'DRAFT'
+# report.save()
+#
+# # Assign to radiologist
+# self.assign_radiologist(report)
+#
+# def complete_report(self, activation):
+# """Finalize the report process"""
+# process = activation.process
+# report = process.radiology_report
+#
+# # Update report status
+# report.status = 'FINAL'
+# report.finalized_datetime = timezone.now()
+# report.save()
+#
+# # Mark process as completed
+# process.report_distributed = True
+# process.save()
+#
+# # Send distribution notifications
+# self.distribute_final_report(report)
+#
+# def end_report(self, activation):
+# """End the report workflow"""
+# process = activation.process
+#
+# # Generate report metrics
+# self.generate_report_metrics(process.radiology_report)
+#
+# # Helper methods
+# def assign_radiologist(self, report):
+# """Assign radiologist to report"""
+# # This would implement radiologist assignment logic
+# pass
+#
+# def distribute_final_report(self, report):
+# """Distribute final report"""
+# # Notify referring physician
+# if report.study.referring_physician and report.study.referring_physician.email:
+# send_mail(
+# subject=f'Final Report Available: {report.study.accession_number}',
+# message=f'Final radiology report is available for {report.study.patient.get_full_name()}.',
+# from_email='radiology@hospital.com',
+# recipient_list=[report.study.referring_physician.email],
+# fail_silently=True
+# )
+#
+# def generate_report_metrics(self, report):
+# """Generate report performance metrics"""
+# # This would generate reporting metrics
+# pass
+#
+#
+# class QualityAssuranceProcess(Process):
+# """
+# Viewflow process model for radiology quality assurance
+# """
+# study_id = CharField(max_length=50, help_text='Study identifier')
+# qa_type = CharField(max_length=20, help_text='Type of QA review')
+#
+# # Process status tracking
+# qa_initiated = models.BooleanField(default=False)
+# images_reviewed = models.BooleanField(default=False)
+# report_reviewed = models.BooleanField(default=False)
+# discrepancies_identified = models.BooleanField(default=False)
+# feedback_provided = models.BooleanField(default=False)
+# qa_completed = models.BooleanField(default=False)
+#
+# class Meta:
+# verbose_name = 'Quality Assurance Process'
+# verbose_name_plural = 'Quality Assurance Processes'
+#
+#
+# class QualityAssuranceFlow(Flow):
+# """
+# Radiology Quality Assurance Workflow
+#
+# This flow manages quality assurance reviews including
+# image quality, report accuracy, and peer review.
+# """
+#
+# process_class = QualityAssuranceProcess
+#
+# # Flow definition
+# start = (
+# flow_func(this.start_qa_review)
+# .Next(this.review_images)
+# )
+#
+# review_images = (
+# flow_view(ImageQualityReviewView)
+# .Permission('radiology.can_review_image_quality')
+# .Next(this.review_report)
+# )
+#
+# review_report = (
+# flow_view(ReportQualityReviewView)
+# .Permission('radiology.can_review_report_quality')
+# .Next(this.identify_discrepancies)
+# )
+#
+# identify_discrepancies = (
+# flow_func(this.assess_discrepancies)
+# .Next(this.provide_feedback)
+# )
+#
+# provide_feedback = (
+# flow_view(QAFeedbackView)
+# .Permission('radiology.can_provide_qa_feedback')
+# .Next(this.finalize_qa)
+# )
+#
+# finalize_qa = (
+# flow_func(this.complete_qa_review)
+# .Next(this.end)
+# )
+#
+# end = flow_func(this.end_qa_review)
+#
+# # Flow functions
+# def start_qa_review(self, activation):
+# """Initialize the QA review process"""
+# process = activation.process
+#
+# # Notify QA staff
+# self.notify_qa_staff(process.study_id, process.qa_type)
+#
+# def assess_discrepancies(self, activation):
+# """Assess for discrepancies"""
+# process = activation.process
+#
+# # Check for discrepancies
+# discrepancies = self.check_discrepancies(process.study_id)
+#
+# if discrepancies:
+# process.discrepancies_identified = True
+# process.save()
+#
+# # Alert QA supervisor
+# self.alert_qa_supervisor(process.study_id, discrepancies)
+#
+# def complete_qa_review(self, activation):
+# """Finalize the QA review process"""
+# process = activation.process
+#
+# # Mark QA as completed
+# process.qa_completed = True
+# process.save()
+#
+# # Generate QA report
+# self.generate_qa_report(process.study_id, process.qa_type)
+#
+# def end_qa_review(self, activation):
+# """End the QA review workflow"""
+# process = activation.process
+#
+# # Update QA metrics
+# self.update_qa_metrics(process.study_id, process.qa_type)
+#
+# # Helper methods
+# def notify_qa_staff(self, study_id, qa_type):
+# """Notify QA staff"""
+# qa_staff = User.objects.filter(
+# groups__name='Radiology QA'
+# )
+#
+# for staff in qa_staff:
+# send_mail(
+# subject=f'QA Review Required: {study_id}',
+# message=f'{qa_type} QA review required for study {study_id}.',
+# from_email='radiology@hospital.com',
+# recipient_list=[staff.email],
+# fail_silently=True
+# )
+#
+# def check_discrepancies(self, study_id):
+# """Check for discrepancies"""
+# # This would implement discrepancy checking logic
+# return []
+#
+# def alert_qa_supervisor(self, study_id, discrepancies):
+# """Alert QA supervisor of discrepancies"""
+# supervisors = User.objects.filter(
+# groups__name='Radiology QA Supervisors'
+# )
+#
+# for supervisor in supervisors:
+# send_mail(
+# subject=f'QA Discrepancies Found: {study_id}',
+# message=f'Quality assurance discrepancies identified for study {study_id}.',
+# from_email='radiology@hospital.com',
+# recipient_list=[supervisor.email],
+# fail_silently=True
+# )
+#
+# def generate_qa_report(self, study_id, qa_type):
+# """Generate QA report"""
+# # This would generate QA report
+# pass
+#
+# def update_qa_metrics(self, study_id, qa_type):
+# """Update QA metrics"""
+# # This would update QA metrics
+# pass
+#
+#
+# class EquipmentMaintenanceProcess(Process):
+# """
+# Viewflow process model for radiology equipment maintenance
+# """
+# equipment_id = CharField(max_length=50, help_text='Equipment identifier')
+# maintenance_type = CharField(max_length=20, help_text='Type of maintenance')
+#
+# # Process status tracking
+# maintenance_scheduled = models.BooleanField(default=False)
+# equipment_inspected = models.BooleanField(default=False)
+# maintenance_performed = models.BooleanField(default=False)
+# quality_testing_completed = models.BooleanField(default=False)
+# equipment_calibrated = models.BooleanField(default=False)
+# equipment_returned = models.BooleanField(default=False)
+#
+# class Meta:
+# verbose_name = 'Equipment Maintenance Process'
+# verbose_name_plural = 'Equipment Maintenance Processes'
+#
+#
+# class EquipmentMaintenanceFlow(Flow):
+# """
+# Radiology Equipment Maintenance Workflow
+#
+# This flow manages equipment maintenance including scheduling,
+# inspection, repair, calibration, and quality testing.
+# """
+#
+# process_class = EquipmentMaintenanceProcess
+#
+# # Flow definition
+# start = (
+# flow_func(this.start_equipment_maintenance)
+# .Next(this.schedule_maintenance)
+# )
+#
+# schedule_maintenance = (
+# flow_view(MaintenanceSchedulingView)
+# .Permission('radiology.can_schedule_maintenance')
+# .Next(this.inspect_equipment)
+# )
+#
+# inspect_equipment = (
+# flow_view(EquipmentInspectionView)
+# .Permission('radiology.can_inspect_equipment')
+# .Next(this.perform_maintenance)
+# )
+#
+# perform_maintenance = (
+# flow_view(MaintenanceExecutionView)
+# .Permission('radiology.can_perform_maintenance')
+# .Next(this.quality_testing)
+# )
+#
+# quality_testing = (
+# flow_view(QualityTestingView)
+# .Permission('radiology.can_perform_quality_testing')
+# .Next(this.calibrate_equipment)
+# )
+#
+# calibrate_equipment = (
+# flow_view(EquipmentCalibrationView)
+# .Permission('radiology.can_calibrate_equipment')
+# .Next(this.return_equipment)
+# )
+#
+# return_equipment = (
+# flow_func(this.complete_equipment_maintenance)
+# .Next(this.end)
+# )
+#
+# end = flow_func(this.end_equipment_maintenance)
+#
+# # Flow functions
+# def start_equipment_maintenance(self, activation):
+# """Initialize the equipment maintenance process"""
+# process = activation.process
+#
+# # Notify maintenance staff
+# self.notify_maintenance_staff(process.equipment_id, process.maintenance_type)
+#
+# # Take equipment offline
+# self.take_equipment_offline(process.equipment_id)
+#
+# def complete_equipment_maintenance(self, activation):
+# """Finalize the equipment maintenance process"""
+# process = activation.process
+#
+# # Mark equipment as available
+# self.return_equipment_to_service(process.equipment_id)
+#
+# # Mark process as completed
+# process.equipment_returned = True
+# process.save()
+#
+# # Notify completion
+# self.notify_maintenance_completion(process.equipment_id)
+#
+# def end_equipment_maintenance(self, activation):
+# """End the equipment maintenance workflow"""
+# process = activation.process
+#
+# # Generate maintenance report
+# self.generate_maintenance_report(process.equipment_id, process.maintenance_type)
+#
+# # Helper methods
+# def notify_maintenance_staff(self, equipment_id, maintenance_type):
+# """Notify maintenance staff"""
+# maintenance_staff = User.objects.filter(
+# groups__name='Radiology Maintenance'
+# )
+#
+# for staff in maintenance_staff:
+# send_mail(
+# subject=f'Equipment Maintenance Required: {equipment_id}',
+# message=f'{maintenance_type} maintenance required for equipment {equipment_id}.',
+# from_email='maintenance@hospital.com',
+# recipient_list=[staff.email],
+# fail_silently=True
+# )
+#
+# def take_equipment_offline(self, equipment_id):
+# """Take equipment offline for maintenance"""
+# # This would update equipment status
+# pass
+#
+# def return_equipment_to_service(self, equipment_id):
+# """Return equipment to service"""
+# # This would update equipment status
+# pass
+#
+# def notify_maintenance_completion(self, equipment_id):
+# """Notify maintenance completion"""
+# # This would notify relevant staff
+# pass
+#
+# def generate_maintenance_report(self, equipment_id, maintenance_type):
+# """Generate maintenance report"""
+# # This would generate maintenance report
+# pass
+#
+#
+# # Celery tasks for background processing
+# @celery.job
+# def auto_schedule_studies():
+# """Background task to automatically schedule imaging studies"""
+# try:
+# # This would perform automated study scheduling
+# return True
+# except Exception:
+# return False
+#
+#
+# @celery.job
+# def monitor_report_turnaround_times():
+# """Background task to monitor report turnaround times"""
+# try:
+# # This would monitor reporting performance
+# return True
+# except Exception:
+# return False
+#
+#
+# @celery.job
+# def generate_radiology_metrics():
+# """Background task to generate radiology performance metrics"""
+# try:
+# # This would generate performance reports
+# return True
+# except Exception:
+# return False
+#
+#
+# @celery.job
+# def auto_assign_radiologists():
+# """Background task to automatically assign radiologists to studies"""
+# try:
+# # This would auto-assign radiologists
+# return True
+# except Exception:
+# return False
+#
diff --git a/templates/.DS_Store b/templates/.DS_Store
index cb3de779..6ad85e18 100644
Binary files a/templates/.DS_Store and b/templates/.DS_Store differ
diff --git a/templates/billing/bills/bill_detail.html b/templates/billing/bills/bill_detail.html
index df025b37..cf32a32a 100644
--- a/templates/billing/bills/bill_detail.html
+++ b/templates/billing/bills/bill_detail.html
@@ -435,7 +435,7 @@
-
+
diff --git a/templates/billing/bills/bill_form.html b/templates/billing/bills/bill_form.html
index 86077449..1f3e072a 100644
--- a/templates/billing/bills/bill_form.html
+++ b/templates/billing/bills/bill_form.html
@@ -5,479 +5,541 @@
{% block content %}
-
-
-
-
{% if object %}Edit Medical Bill{% else %}Create Medical Bill{% endif %}
-
-
-
+
+
+
+
{% if object %}Edit Medical Bill{% else %}Create Medical Bill{% endif %}
+
+
+
-