Location and visit parameters
In Calendar Planning, a location is a point that an employee must visit and handle. Special locations, such as the starting and end points of the route, are also considered during planning. Multiple visits can be planned for one location.
When planning with Excel, location characteristics are specified on the locations
sheet, and visit parameters are specified on the visits
sheet. When planning via the API, all parameters are specified in the locations
object.
Basic parameters
- ID
-
Each location must have a unique numeric or string ID set in the
id
field. The ID must be unique within a single request. - Additional ID
-
You can specify an additional numeric or string location ID in the
ref
field. - Name
-
You can specify the location name in the
title
field. - Description
-
The location description is given in the
description
field. - Comment
-
You can enter a comment about the location, such as info about parking or a link to the website, in the
comments
field. - Phone number
-
You can pass a phone number to contact a location in the
phone
field. - Address and coordinates
-
Location coordinates (latitude and longitude) are passed in the
point.lat
andpoint.lon
fields. They are specified in WGS84WGS84. You can geocode an address (convert an address in open format to geographical coordinates) in advance. -
Make sure that latitude and longitude aren't mixed up and no pairs of coordinates are too different from the others (this usually indicates geocoding errors: during planning an address like this will be too far away from the others, and this location won't be included in any routes).
-
You can additionally specify a postal address in the
address
field for the convenience of the mobile employee handling this location. - Handling time
-
The handling time allocated to an employee to visit a location is specified in seconds in the
service_duration_s
field. - Location type
-
By default, locations have the
check-in
type. During planning, you can use special locations withtype
=base
to indicate the location where an employee starts or ends the route (home, office).
Number and frequency of visits to locations
You can plan a visit to a location for an arbitrary period. It's assumed that the schedule for visiting the location is the same for each planning period.
The number of visits to the location within a planning period is specified in the visit_count
field. Penalties may be imposed for skipped or extra visits:
penalty.drop
: Fixed penalty if the location hasn't been visited once.penalty.visit_count.fixed
: Fixed penalty if at least one visit to the location was skipped or at least one extra visit was made.penalty.visit_count.per_visit
: Penalty for each skipped or extra visit to the location.
Penalties can also be imposed for skipping particular types of visits.
The min_days_between_visits
and max_days_between_visits
set the minimum and maximum interval between visits. Days are counted inclusively, which means that one day passes between visits on neighboring days. For example, if the interval value is 1, the visit frequency is set to every day. If this value is 2, visits are planned for every other day.
The date of the last visit to a location before the start of planning is specified in the last_visit_date
field. It must precede the planning start date specified in the options.date
field. The interval between this date and the date of the first visit to a location within a planning period must comply with the min_days_between_visits
and max_days_between_visits
restrictions.
The following penalties can be imposed for violating the restrictions:
penalty.min_days_between_visits.fixed
andpenalty.min_days_between_visits.per_day
penalty.max_days_between_visits.fixed
andpenalty.max_days_between_visits.per_day
Each penalty consists of a fixed part for an instance of violation and a variable part calculated for each day or each visit violating the restriction. Default penalty values are 0.
Note
Too severe restrictions in the min_days_between_visits
and max_days_between_visits
parameters may lead to an uneven workload distribution on different days and result in an overall ineffective solution.
Example
Visits to 17 locations are planned over a 30-day period. Locations 1 to 5 must be visited in the evening, while locations 6 to 17 must be visited in the morning. Each location must be visited 8 times, with a maximum interval of 6 days between visits and a minimum interval of 3 days. Visits are distributed between 2 employees, one of them working in the morning and the other one working in the evening.
API request (JSON) ⋅ API response
Days of visits
You can specify days of visits for a particular location:
allowed_days
: Days when you can visit the location. If no value is set, employees can visit the location on all working days. Theoptions.working_days_in_week
parameter that sets the number of working days in a week is considered: ifoptions.working_days_in_week
= 7, the location can be visited on any day.preferred_days
: Days when you should visit the location.mandatory_days
: Days when you must visit the location. If the field contains more days than thevisit_count
field, the solution can't be built.denied_days
: Days when you mustn't visit the location. They are excluded from the days set by other parameters. You can use this field to specify non-scheduled holidays.
The following formats are supported to denote days:
- Full names of days in English, starting with a capital letter: "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", and "Sunday".
- 2- and 3-letter abbreviations: "Mo", "Mon", "Tu", "Tue", "We", "Wed", "Th", "Thu", "Fr", "Fri", "Sa", "Sat", "Su", "Sun".
- Dates in YYYY-MM-DD format.
- Numbers of days from the start of planning, starting with 0.
A penalty can be imposed for visiting a location on any day other than those specified in preferred_days
: a fixed penalty for an instance of violating penalty.preferred_days.fixed
or a penalty for each day planned in violation of the penalty.preferred_days.per_day
restriction.
Note
Too severe restrictions in the allowed_days
, preferred_days
, and mandatory_days
fields may lead to an uneven workload distribution on different days and result in an overall ineffective solution.
Example of an API request
A location can be visited on any day except Sunday. Mondays, Wednesdays, Fridays, and June 10 are preferred. Visits are mandatory on the first, third, and sixth days, as well as on all Mondays within the planning period. Visits on June 12 are prohibited.
{
"locations": [
{
"id": "Location1",
"allowed_days": ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat"],
"preferred_days": ["Mo", "We", "Fr", "2023-06-10"],
"mandatory_days": [0, 2, 5, "Monday"],
"denied_days": ["2023-06-12"]
}
]
}
Location time windows
Locations can have time windows, which are intervals in time during which an employee can visit them. We recommend specifying realistic, not too narrow time windows.
If time windows aren't specified, visits to this location can be made at any time between 00:00 and 24:00.
To define a time window, use the time_window
field.
The time window can be defined in one of the following formats:
07:00:00 – 23:00:00
: The time window starts at 7:00 and ends at 23:00 on the current day.2019-10-10T07:00:00+03:00/2019-10-10T23:00:00+03:00
: The time window for a specific date and time zone (read as YYYY-MM-DDThh:mm:ss±hh:mm).
You can specify multiple time windows (for example, if a location has breaks). If you're planning via Excel, set multiple columns in your spreadsheet: time_window.0
, time_window.1
, and so forth. In API requests, instead of the time_window
field, specify time_windows
, which is an array of time_window
elements. The visit will be planned within one of the specified time windows.
Alert
The single time_window
field and the time_windows
array are incompatible: for each given location, you must use only one of the two options.
The time_window.N
windows for one location (in a single time_windows
array) mustn't overlap. For example, you can't specify 9:00–12:00 and 11:00–14:00 windows at the same time.
You can set an external hard window hard_time_window
for each time window (be it a single window or an array of them).
The used_time_window
and used_hard_time_window
fields in the API response will contain information about the used time window.
The following penalties are imposed for violating time windows: penalty.out_of_time
(for any violation), penalty.early
(for early arrival), and penalty.late
(for delay). Each of these penalties can have a fixed
part for the violation itself and a per_minute
variable for each minute of the violation.
By default, the handling time doesn't have to fit in the location time window (it's acceptable for an employee to arrive at the location at 17:59, even though the time window ends at 18:00).
If you set penalize_late_service
to true
(false
by default), penalties are imposed when a visit to a location is completed late (after the end of the selected time window).
Location tags
You can select employees for handling a location based on specific characteristics, such as their qualifications or specialization. Such requirements are set using tags and can be mandatory or optional.
Mandatory requirements are set for a location in the required_tags
field: at least one employee tag must match at least one mandatory location tag. For more information about planning based on specific employee requirements, see Planning based on employees' skills.
If you want to assign a location to a specific employee, you can set a unique tag for that employee and add the same tag to the mandatory location tags. For more information, see Assigning a location using tags.
Optional location requirements are specified in the optional_tags
field. These requirements can be ignored during planning; however, if the location and employee tags match, this affects the route cost.
The optional_tags.N.tag
value and the optional_tags.N.value
weight are specified for each optional tag. The weight can be positive or negative. If an optional location tag matches an employee's tag from the tags
field on the employees
sheet (employees.tags
in the API request), the weight is deducted from the route cost; if an optional location tag matches an employee's tag from the excluded_tags
field on the employees
sheet (employees.excluded_tags
in the API request), the weight is added to the route cost.
You can also use optional tags to set the priority of visiting a location. For more information, see Prioritization using tags.
Example
You need to visit 49 locations. Some locations have optional tags:
morning
: 6 locations with a weight of 500.VIP
: 3 locations with a weight of 1000.
Employee 1 starts and ends their working day early, so they have the morning
tag. Employee 2 has special skills, so they have the VIP
tag.
As a result of planning, the requirements were met in most cases: employee 1 visits 4 out of 5 locations, and employee 2 visits all VIP locations.
API request (JSON) ⋅ API response
Location incompatibility
Individual locations may have special visit conditions. They may be mutually exclusive for different locations, and you can't visit such locations within the same route. For example, an employee may need different workwear to visit a medical laboratory and a construction warehouse. Location characters that determine their incompatibility are specified in the load_types
field. For example, you can specify load_types
= clean
for a medical laboratory.
For a single location, you can specify multiple characteristics, separating them with commas. For example, if location handling requires working with food products in a cold storage, you can specify load_types
= food,cold
.
You can't fill in the load_types
field for base
locations.
Location incompatibility is set in the incompatible_load_types
field: on the options
sheet for all routes, and on the employees
sheet for individual employees. For more information, see Location incompatibility.
Multiple employees handling a single location
By default, one employee is assigned to one location. However, you can allow multiple employees to visit the same location on different days. To do this, set the field options.allow_multiple_visitors
to true
.
You can limit the maximum number of employees who can visit the same location using the location.max_distinct_visitors
parameter. A penalty for violating this limit may either be fixed penalty.max_distinct_visitors.fixed
or variable for each visitor above the penalty.max_distinct_visitors.per_visitor
value.
When calculating the location handling cost, you can set a fixed cost for more than one employee visiting the location (cost.additional_visitors.fixed
) and a cost for each additional employee visiting the location, starting with the second one (cost.additional_visitors.per_visitor
).
To estimate the cost of the planned solution, use the following metrics:
-
additional_visitors_cost
: Total cost of engaging additional employees. -
total_locations_cost
: Total cost of handling all locations. -
total_employee_cost
: Total cost of engaging employees handling all locations.
Example of an API request
A maximum of 2 employees can visit a location. In this case, the cost of handling a location will be small, just 20,000 units. If a visit schedule is planned for 3 employees, a large penalty of 2,000,000 units will be added to the cost.
{
"options": {
"allow_multiple_visitors": true
},
"locations": [
{
"penalty": {
"max_distinct_visitors": {
"fixed": 1000000,
"per_visitor": 1000000
}
},
"cost": {
"additional_visitors": {
"fixed": 10000,
"per_visitor": 10000
}
},
"max_distinct_visitors": 2
}
]
}
Priorities
You can prioritize visits to locations using the priority
parameter on the locations
sheet. It can be set by a non-negative integer. The lower the parameter value, the higher the location's priority. Multiple locations can have the same priority.
An employee can visit locations with lower priority only after visiting all locations with higher priority within the planned period.
Locations for which no priority is specified may be visited in any order.
For an example of using priorities, see Setting priorities.
Visit types
You can set different visit types for a location if different types of works are planned: for example, "Stocking" and "Inventory" for a store. You can also set a sequence of visits of different types for a location. For example, inventory is performed during every fifth visit, and stocking is done on all other days.
Visit types are specified on the visits
sheet in Excel (in the locations.visits
array in the API request).
You can set individual parameters and limits for each visit type:
location.id
: ID of the location the visit type is related to.title
: Visit type name.service_duration_s
: Handling time for this type of visit.drop
: Penalty for skipping visits of this type. If set, it replaces thepenalty.visit_count.per_visit
value for this type of visits. For more information, see Number and frequency of visits to locations.allowed_days
: Days on which visits of this type are allowed.preferred_days
: Days on which visits of this type are preferred.denied_days
: Days on which visits of this type are prohibited.
The following formats are supported to denote days:
- Full names of days in English, starting with a capital letter: "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", and "Sunday".
- 2- and 3-letter abbreviations: "Mo", "Mon", "Tu", "Tue", "We", "Wed", "Th", "Thu", "Fr", "Fri", "Sa", "Sat", "Su", "Sun".
- Dates in YYYY-MM-DD format.
- Numbers of days from the start of planning, starting with 0.
When planning routes with Excel, you must specify the handling time (service_duration_s
) on the visits
sheet for each visit type. If you plan via the API and don't set service_duration_s
for a visit type, the parameter set for the location as a whole will be used.
Alert
Parameters set for a visits visit type have a higher priority and completely override similar parameters set for the location as a whole. If no parameters are specified for a visit type, similar parameters specified for the location will be used.
If visits visit types aren't defined, all visits to the location will be the same and will comply with the location settings.
Visits will be made sequentially in the specified order. If fewer visit types are specified than need to be completed within a planning period (the visit_count
value), visits will be repeated cyclically. If there are more visit types than need to be completed within a planning period, extra visits will be ignored.
For example, you need to make 10 visits within a planning period. 3 visit types are specified for the location: "Inventory" (I), the first one; and "Stocking" (S), the second and third ones. The visits will be planned in the following order: I, S, S, I, S, S, I, S, S, I.
Example of an API request
In accordance with the settings below, 4 "Inventory" (I) and 6 "Stocking" (S) visits will be planned in the following order: I, S, S, I, S, S, I, S, S, I.
{
"locations": [
{
"service_duration_s": 1800,
"allowed_days": [ "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" ],
"preferred_days": ["Mon", "Wed", "Fri"],
"denied_days": [
"2023-06-12"
],
"visit_count": 10,
"visits": [
{
"title": "Inventory",
"service_duration_s": 3600,
"drop": 1000000,
"allowed_days": [ "Mon", "Tue" ],
"preferred_days": ["Mon"]
},
{
"title": "Stocking"
},
{
"title": "Stocking"
}
],
"penalty": {
"drop": {
"fixed": 100000,
"per_visit": 10000
},
"preferred_days": {
"fixed": 10000,
"per_visit": 1000
}
}
}
]
}
You can set different priorities for different visit types. For more information, see Prioritization using penalties.