Posts Tagged ‘resources’

Troubleshooting Field Service

Tuesday, October 20th, 2009

A thing that has been bothering our project for some time now is vague behaviour of the Autonomous Scheduler. We found out that the key problem of this behaviour was the table CAC_SR_OBJECT_CAPACITY. This table contains the capacity for your resources. So if you’re wondering why your resource isn’t getting any tasks assigned, you might want to check the corresponding record in this table.

Capacity is defined as the availability in a certain trip, so basically when you run the process Generate Field Service Trips, this table is filled with capacity records. Next, all task assignments within this trip are deducted and if there’s time left, you get a positive number in the AVAILABLE_HOURS column. So far so good.

It sometimes happens the available hours is a negative number. This basically means something went wrong. Logically the Scheduler will not assign any tasks to a person without any availability, especially when your availability is negative! Use the query below to figure out which resources have a negative availability.

select source_name, object_id, count(1)
from cac_sr_object_capacity b
, jtf_rs_defresources_v c
where available_hours < -30
and c.resource_id = b.object_id
and trunc(start_date_time) = '20-10-2009'
group by source_name, object_id;

This basically shows which resources have a problem. We use -30 to exclude any resources who have double tasks assigned, which sometimes leads to a negative number, just below 0. Less than -30 is considered a problem for us, but you might want to use a higher number, 0 or -10 for example. The object_id is what you need in the next query.


select a.creation_date "assignment creation date"
, a.resource_id "resource id"
, a.assignment_status_id "assignment status id"
, a.booking_start_date "assignment start"
, a.booking_end_date "assignment end"
, a.object_capacity_id
, b.object_id "resource id - capacity"
, b.start_date_time "capacity start"
, b.end_date_time "capacity end"
, b.available_hours "available hours"
, c.planned_start_date
, c.planned_end_date
, c.scheduled_start_date
, c.scheduled_end_date
, c.planned_effort
, c.planned_effort_uom
, a.sched_travel_duration
, a.sched_travel_duration
, c.task_number
from jtf_task_assignments a
, cac_sr_object_capacity b
, jtf_tasks_b c
where a.object_capacity_id = b.object_capacity_id
and c.task_id = a.task_id
and object_id = 100004376
and available_hours < -30
and trunc(start_date_time) = '20-10-2009';

This yields an overview of all tasks linked to the capacity records. For some reason this usually contains all kinds of tasks that should not be there. Mostly the assignments are from repeating tasks in our case. Erasing these task is the first part of the solution.

To fix the availability, i.e. to recalculate it, you have to run the Generate Field Service Trips concurrent program with the FIX option. (what's in a name). If the concurrent program finished succesfully, you're done. If it ends in error, you missed a resource.

Good luck and let me know if it helped.

Oracle Territory Management and Scheduler

Tuesday, April 28th, 2009

With two customers I have worked for with Field Service, both of them had the following requirement: “schedule tasks to internal employees first and if there’s no capacity, pick an external technician”. This requirement cannot easily be met. In the most simple way, plan your tasks in two steps

  1. schedule all tasks to employees, reject the ones which don’t meet all the criteria, set a reject-status;
  2. schedule all rejects to external technicians.

To do this, you need to define two territories, one with all employees, one with all external technicians. Add a match criterium “task status = reject” to the second one. For rejected tasks, Scheduler will choose the second territory to pick all the external technicians and evaluate the skills, capacity and other parameters.

This might work fine if you can afford to batch schedule all of your tasks. If you’re working in a real-time environment, this is harder. If your business has a high volume of appointments per day, appointments that need to be scheduled while the customer is on the phone, the call center agent needs to be able to promise something. Promises are sacred. Scheduler has a window to promise option that will give the call center agent windows to pick from. When Scheduler selects the right resources to turn into windows, it takes only the employees, not the external ones (because of the match criteria). This is logical, because you want to optimize internal resoruces first, before turning to external technicians. The thing is, when you run out of employees, you run out of windows. How are you optimizing now?

One possibility would be to put all internal employees and external technicians into one territory, create a second and a third territory with a match criterium and put all of the employees in the second, and all the external technicians into the third:

  1. All resources
  2. Internal employees, match criterium: task status = from_call_center (or whatever you choose)
  3. External technicians, match criterium: task status = reject

The call center agent would be able to get its windows / capacity from all of the resources, i.e. territory one. The Planning Desk or Dispatchers would then reschedule all planned tasks, which have the status from_call_center. This way all internal resources are ‘optimized’. Dispatchers might want to check the result and when it is satisfactory, they’ll schedule all of the tasks which have been rejected by the previous run. All the rejects will now be scheduled to external engineers.

This should work. And yes, you’re still batch scheduling your resources, something you rather don’t.

A common misunderstanding is that the Rank in Territories is considered by the Scheduler, this is not the case! Rank only plays a role in selecting a resource as input for the Scheduler. Scheduler then discards all ranking and evaluates all resources as equals. Would be nice when Rank did play a role, especially for real time scheduling, wouldn’t it? Enhancement Request 6878526, please add your “I want it too”  remark.