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