# """ # 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 #