Scheduling tasks to employees with overrides for vacation

117 Views Asked by At

I am trying to implement a feature where employees are rotating a tasks assignment based on the schedule created. In most cases, employees are assigned a task on a rotating daily, weekly, biweekly, or monthly basis.

For example, we have 4 employees: John, Peter, Avit, Jane For a daily schedule, John may be responsible for the task the first week, Peter the second week, etc

There are also times where an employee might be on vacation. For example, John is on PTO for the first 2 days while he is assigned to the task and Avit takes over for those 2 days, when John is back on Day 3 he takes back the task assignment. I am trying to figure out how I can implement such a scheduling feature with ice_cube.

I know how to create a schedule with reoccurrence and exceptions. But I am not sure how to incorporate this with the concept of rotating amongst a set of users with overrides.

I have implemented a model called ScheduleUser, which stores the user_id and priority value. I have a delayed job that runs on each occurrence date/time which rotates the value in the priority column for each user. The person assigned to the task is the one with the highest priority.

This works fine for the simple use case, however when I have to override (partially or for the entire duration) an employee assignment then this doesn't work.

1

There are 1 best solutions below

1
Chiperific On

Based on your other SO question on this topic, I suggest you have a field in your database that allows you to exclude users from the schedule_users method.

validates_presence_of :name, :start, :frequency, :project
    
  def next_occurrence
    ice_cube_schedule.next_occurrence.start_time
  end

  def jobs
    Delayed::Job.where('handler LIKE ?', "%Schedule/#{id}\%")
  end

  def on_call_user
    # This should not include any users that are unavailable
    schedule_users.max_by(&:priority).user if users.present?
  end

  def priority(user)
    # This should not include any users that are unavailable
    schedule_users.where(user: user).first.try(:priority)
  end

  ...
end

So, in your User model you could have a scope that prevents unavailable users from being selected:

class User
  # we will need a boolean database field called "unavailable"

  scope :available, -> { where(unavailable: false) }

  ...
end

Then you can call User.all.available (or @users.available) to only get "available" users.

What about covering for each other?

Maybe I'm over-simplifying this, your example is quite a complex piece of logic:

John is on PTO for the first 2 days while he is assigned to the task and Avit takes over for those 2 days, when John is back on Day 3 he takes back the task assignment

If John is already on PTO, why would he be assigned a task? Why wouldn't it just default to Avit? This is what I'm driving at above.

If you want a way to manually make John take over the task on Day 3, you just need to destroy or edit the existing, active ice_cube schedule, right?