def staff_or_send_request_inquiries(staffbot, request, worker_batch_size): # Get Workers that haven't already received an inquiry. workers_with_inquiries = (StaffingRequestInquiry.objects.filter( request=request).distinct().values_list( 'communication_preference__worker__id', flat=True)) required_role = get_role_from_counter(request.required_role_counter) # Sort Worker Certifications by their staffing priority first, # and then randomly within competing staffing priorities. worker_certifications = (WorkerCertification.objects.filter( role=required_role, task_class=WorkerCertification.TaskClass.REAL, certification__in=( request.task.step.required_certifications.all())).order_by( '-staffing_priority', '?')) available_worker_certifications = (worker_certifications.filter( worker__availabilities__week=first_day_of_the_week())) uninquired_worker_certifications = (worker_certifications.exclude( worker__id__in=workers_with_inquiries)) successfully_staffed = _attempt_to_automatically_staff( staffbot, request, available_worker_certifications) sending_inquiries = StaffBotRequest.Status.SENDING_INQUIRIES.value # We consider StaffBotRequests that are done sending inquiries # when auto-staffing, since it's possible for a worker to have new # auto-staffing availability for a request that has already been # sent to them (e.g., the day after receiving a request, their new # availability kicks in). Once we reach the branch below, we only # want to send new request inquiries for requests that aren't # `DONE_SENDING_INQUIRIES`. if ((not successfully_staffed) and (request.status == sending_inquiries)): _send_request_inquiries(staffbot, request, worker_batch_size, uninquired_worker_certifications)
def _send_request_inquiries(staffbot, request, worker_batch_size, worker_certifications): inquiries_sent = 0 required_role = get_role_from_counter(request.required_role_counter) contacted_workers = set() for certification in worker_certifications: worker = certification.worker if worker.id in contacted_workers: continue contacted_workers.add(worker.id) if _is_worker_assignable(worker, request.task, required_role): staffbot.send_task_to_worker(worker, request) inquiries_sent += 1 if inquiries_sent >= worker_batch_size: break # check whether all inquiries have been sent out. if inquiries_sent < worker_batch_size: message_experts_slack_group( request.task.project.slack_group_id, ('All staffing requests for task {} have been sent!'.format( request.task))) request.status = StaffBotRequest.Status.DONE_SENDING_INQUIRIES.value request.last_inquiry_sent = timezone.now() request.save()
def _attempt_to_automatically_staff(staffbot, request, worker_certifications): successfully_staffed = False required_role = get_role_from_counter(request.required_role_counter) attempted_workers = set() new_task_available_type = ( CommunicationPreference.CommunicationType.NEW_TASK_AVAILABLE.value) previously_opted_in_method = ( StaffingRequestInquiry.CommunicationMethod.PREVIOUSLY_OPTED_IN.value) for certification in worker_certifications: worker = certification.worker if worker.id in attempted_workers: continue attempted_workers.add(worker.id) if (_is_worker_assignable(worker, request.task, required_role) and _can_handle_more_work_today(worker, request.task)): communication_preference = (CommunicationPreference.objects.get( communication_type=new_task_available_type, worker=worker)) staffing_request_inquiry = StaffingRequestInquiry.objects.create( communication_preference=communication_preference, communication_method=previously_opted_in_method, request=request) handle_staffing_response(worker, staffing_request_inquiry.id, is_available=True) successfully_staffed = True break return successfully_staffed
def send_request_inquiries(staffbot, request, worker_batch_size): # Get Workers that haven't already received an inquiry. workers_with_inquiries = (StaffingRequestInquiry.objects.filter( request=request).distinct().values_list( 'communication_preference__worker__id', flat=True)) required_role = get_role_from_counter(request.required_role_counter) # Sort Worker Certifications by their staffing priority first, # and then randomly within competing staffing priorities. worker_certifications = (WorkerCertification.objects.exclude( worker__id__in=workers_with_inquiries).filter( role=required_role, task_class=WorkerCertification.TaskClass.REAL, certification__in=( request.task.step.required_certifications.all())).order_by( '-staffing_priority', '?')) _send_request_inquiries(staffbot, request, worker_batch_size, worker_certifications)
def send_request_inquiries(staffbot, request, worker_batch_size): # Get Workers that haven't already received an inquiry. workers_with_inquiries = (StaffingRequestInquiry.objects.filter( request=request).distinct().values_list( 'communication_preference__worker__id', flat=True)) # Sort Workers by their staffing priority first, and then randomly # within competing staffing priorities. workers = (Worker.objects .exclude(id__in=workers_with_inquiries) .order_by('-staffing_priority', '?')) required_role = get_role_from_counter(request.required_role_counter) inquiries_sent = 0 for worker in workers: try: check_worker_allowed_new_assignment(worker) if (is_worker_certified_for_task(worker, request.task, required_role, require_staffbot_enabled=True) and not request.task.is_worker_assigned(worker)): staffbot.send_task_to_worker(worker, request) inquiries_sent += 1 if inquiries_sent >= worker_batch_size: break except TaskStatusError: pass except TaskAssignmentError: pass # check whether all inquiries have been sent out. if inquiries_sent < worker_batch_size: message_experts_slack_group( request.task.project.slack_group_id, ('All staffing requests for task {} have been sent!' .format(request.task))) request.status = StaffBotRequest.Status.COMPLETE.value request.last_inquiry_sent = timezone.now() request.save()
def send_request_inquiries(staffbot, request, worker_batch_size): # Get Workers that haven't already received an inquiry. workers_with_inquiries = (StaffingRequestInquiry.objects.filter( request=request).distinct().values_list( 'communication_preference__worker__id', flat=True)) # Sort Workers by their staffing priority first, and then randomly # within competing staffing priorities. workers = (Worker.objects.exclude(id__in=workers_with_inquiries).order_by( '-staffing_priority', '?')) required_role = get_role_from_counter(request.required_role_counter) inquiries_sent = 0 for worker in workers: try: check_worker_allowed_new_assignment(worker) if (is_worker_certified_for_task(worker, request.task, required_role, require_staffbot_enabled=True) and not request.task.is_worker_assigned(worker)): staffbot.send_task_to_worker(worker, request) inquiries_sent += 1 if inquiries_sent >= worker_batch_size: break except TaskStatusError: pass except TaskAssignmentError: pass # check whether all inquiries have been sent out. if inquiries_sent < worker_batch_size: message_experts_slack_group( request.task.project.slack_group_id, ('All staffing requests for task {} have been sent!'.format( request.task))) request.status = StaffBotRequest.Status.COMPLETE.value request.last_inquiry_sent = timezone.now() request.save()
def _send_request_inquiries(staffbot, request, worker_batch_size, worker_certifications): inquiries_sent = 0 required_role = get_role_from_counter(request.required_role_counter) contacted_workers = set() for certification in worker_certifications: try: worker = certification.worker if worker.id in contacted_workers: continue contacted_workers.add(worker.id) check_worker_allowed_new_assignment(worker) if (is_worker_certified_for_task(worker, request.task, required_role, require_staffbot_enabled=True) and not request.task.is_worker_assigned(worker)): staffbot.send_task_to_worker(worker, request) inquiries_sent += 1 if inquiries_sent >= worker_batch_size: break except TaskStatusError: pass except TaskAssignmentError: pass # check whether all inquiries have been sent out. if inquiries_sent < worker_batch_size: message_experts_slack_group( request.task.project.slack_group_id, ('All staffing requests for task {} have been sent!'.format( request.task))) request.status = StaffBotRequest.Status.DONE_SENDING_INQUIRIES.value request.last_inquiry_sent = timezone.now() request.save()
def send_request_inquiries(staffbot, request, worker_batch_size): # get names of workers that that already received inquiry worker_usernames = (StaffingRequestInquiry.objects.filter( request=request).values_list( 'communication_preference__worker__user__username', flat=True)) workers = (Worker.objects .exclude(user__username__in=worker_usernames) .order_by('?')) required_role = get_role_from_counter(request.required_role_counter) inquiries_sent = 0 for worker in workers: try: check_worker_allowed_new_assignment(worker) if (is_worker_certified_for_task(worker, request.task, required_role) and not request.task.is_worker_assigned(worker)): staffbot.send_task_to_worker(worker, request) inquiries_sent += 1 if inquiries_sent >= worker_batch_size: break except TaskStatusError: pass except TaskAssignmentError: pass # check whether all inquiries have been sent out. if inquiries_sent < worker_batch_size: message_experts_slack_group( request.task.project.slack_group_id, ('All staffing requests for task {} have been sent!' .format(request.task))) request.status = StaffBotRequest.Status.COMPLETE.value request.save()