Route Planning

route_planning
REPOSITORY
REPOSITORYOCA/route-planning
GIT
GIThttps://github.com/OCA/route-planning.git
GIT FOLDER
GIT FOLDERhttps://github.com/OCA/route-planning/tree/18.0/route_planning
VERSION
VERSION 1.0.0
CATEGORY
CATEGORYUncategorized
LICENSE
LICENSEAGPL-3
APPLICATION
APPLICATIONNo
AUTO-INSTALLABLE
AUTO-INSTALLABLENo
AUTHORS
AUTHORSTecnativa, Odoo Community Association (OCA)
MAINTAINERS
MAINTAINERSTecnativa, Odoo Community Association (OCA)
COMMITTERS
COMMITTERSCarlos Lopez, Weblate, OCA-git-bot, oca-ci
WEBSITE
WEBSITEhttps://github.com/OCA/route-planning
LAST TRACKING UPDATE
LAST TRACKING UPDATE2026-07-06 19:30:11
ODOO DEPENDENCIES
ODOO DEPENDENCIES OCA/geospatial:
    - web_view_leaflet_map
    - web_leaflet_lib
odoo/odoo:
    - mail
    - base
    - base_setup
    - web
    - bus
    - web_tour
    - html_editor
    - base_geolocalize
PYTHON DEPENDENCIES
PYTHON DEPENDENCIES ortools
SYSTEM DEPENDENCIES
SYSTEM DEPENDENCIES Not have
DESCRIPTION
DESCRIPTION
This module allows to manage delivery routes, checkpoints, and visit windows.

Before using this module, you must configure the required master data: **Route Areas**,
**Checkpoints**, and **Routes**. Without this data, the route planning functionality will
not be operational.

## Models

### Route Area

Defines a geographic or logical zone used to group routes. Each area helps organize
delivery operations by region or territory.

### Checkpoint

Represents a specific stop or delivery point within a route. Checkpoints define the
locations that must be visited, along with any time window constraints for the visit.

### Route

A route is an ordered sequence of checkpoints assigned to a specific area. It defines
the order in which checkpoints must be visited, making it possible to optimize daily
or weekly operations for any kind of service or delivery workflow.

### Visit Windows

A visit window defines the time interval during which a checkpoint must be reached.
Windows are configured on the **contact (partner)**, where one or more slots can be
defined specifying the earliest arrival time (*time from*) and the latest allowed
arrival time (*time to*). This allows the same availability constraints to be reused
across different routes and checkpoints.

Code Analysis

Views touched (23)
XML IDNameModelTypeStatus
route_checkpoint_view_calendar route.checkpoint.view.calendar route.checkpoint calendar New
route_checkpoint_view_kanban route.checkpoint.view.kanban route.checkpoint kanban New
route_route_view_calendar route.route.view.calendar route.route calendar New
route_route_view_kanban route.route.view.kanban route.route kanban New
view_partner_form_route res.partner.form.route res.partner xpath Inherits base.view_partner_form
view_partner_geolocalize_form res.partner.form res.partner xpath Inherits base_geolocalize.view_crm_partner_geo_form
view_route_area_form route.area.form route.area form New
view_route_area_list route.area.list route.area list New
view_route_area_search route.area.search route.area search New
view_route_checkpoint_form route.checkpoint.form route.checkpoint form New
view_route_checkpoint_list route.checkpoint.list route.checkpoint list New
view_route_checkpoint_map route.checkpoint leaflet_map New
view_route_checkpoint_search route.checkpoint.search route.checkpoint search New
view_route_create_incident_form route.create.incident.form route.create.incident form New
view_route_incident_type_form route.incident.type.form route.incident.type form New
view_route_incident_type_list route.incident.type.list route.incident.type list New
view_route_incident_type_search route.incident.type.search route.incident.type search New
view_route_route_form route.route.form route.route form New
view_route_route_list route.route.list route.route list New
view_route_route_search route.route.search route.route search New
view_route_visitwindow_template_form route.visitwindow.template.form route.visitwindow.template form New
view_route_visitwindow_template_list route.visitwindow.template.list route.visitwindow.template list New
view_route_visitwindow_template_search route.visitwindow.template.search route.visitwindow.template search New
Models touched (11)

New fields (3)
  • route_area_id Many2one → route.area
    company_dependent=True compute='_compute_route_area_id' readonly=False store=True args: 'route.area'
  • route_visitwindow_ids One2many → route.partner.visitwindow
    args: 'route.partner.visitwindow', 'partner_id'
  • route_visitwindow_template_id Many2one → route.visitwindow.template
    help='Template to pre-fill visit windows for this partner, this field will be cleared after applying the template.' string='Visit Window Template' args: 'route.visitwindow.template'
Public methods (0)

No public methods.

New fields (11)
  • active Boolean
    default=True
  • auto_assign Boolean
    help='Automatically assign this area to partners matching its criteria, based on country, state, and zip code range.'
  • code Char
    required=True
  • company_id Many2one → res.company
    default=<expr> required=True args: 'res.company'
  • country_ids Many2many → res.country
    comodel_name='res.country'
  • name Char
    required=True
  • state_ids Many2many → res.country.state
    comodel_name='res.country.state' domain="[('country_id', 'in', country_ids)]"
  • time_start Float
  • user_id Many2one → res.users
    args: 'res.users'
  • waiting_time Float
    help='Average waiting time at each stop, expressed in minutes.'
  • zip_ids One2many → route.area.zip
    string='Zip ranges' args: 'route.area.zip', 'route_area_id'
Public methods (0)

No public methods.

New fields (3)
  • route_area_id Many2one → route.area
    comodel_name='route.area' ondelete='cascade' required=True
  • zip_from Char
    required=True
  • zip_to Char
    required=True
Public methods (0)

No public methods.

New fields (18)
  • checkpoint_ids One2many → route.checkpoint
    string='Checkpoints' args: 'route.checkpoint', 'origin_checkpoint_id'
  • company_id Many2one → res.company
    related='route_id.company_id' store=True args: 'res.company'
  • date_done Datetime
    copy=False readonly=True
  • date_localization Date
    related='partner_id.date_localization'
  • display_address Char
    compute='_compute_display_address'
  • incident_type_id Many2one → route.incident.type
    copy=False ondelete='restrict' readonly=True tracking=True args: 'route.incident.type'
  • latitude Float
    compute='_compute_latitude' digits=(10, 7) readonly=False store=True
  • longitude Float
    compute='_compute_longitude' digits=(10, 7) readonly=False store=True
  • note Text
  • origin_checkpoint_id Many2one → route.checkpoint
    copy=False help='Original checkpoint when this is created from an incident' readonly=True args: 'route.checkpoint'
  • partner_id Many2one → res.partner
    ondelete='restrict' tracking=True args: 'res.partner'
  • route_id Many2one → route.route
    ondelete='cascade' required=True tracking=True args: 'route.route'
  • route_state Selection
    related='route_id.state' string='Route State'
  • schedule_date Date
    related='route_id.schedule_date' store=True
  • schedule_time Float
    copy=False tracking=True
  • sequence Integer
    copy=False default=10 tracking=True
  • state Selection
    default='draft' tracking=True args: [('draft', 'Draft'), ('planned', 'Planned'), ('done', 'Done'), ('incident', 'Incident')]
  • user_id Many2one → res.users
    related='route_id.user_id' store=True args: 'res.users'
Public methods (7)
  • action_back_to_planned(self)
  • action_done(self)
  • action_draft(self)
  • action_open_checkpoint(self)
  • action_planned(self)
  • action_view_origin_checkpoint(self)
  • write(self, vals)

New fields (3)
  • checkpoint_id Many2one → route.checkpoint
    string='Checkpoint' args: 'route.checkpoint'
  • incident_type_id Many2one → route.incident.type
    required=True args: 'route.incident.type'
  • note Text
Public methods (2)
  • action_create_incident(self)
  • default_get(self, fields_list)

New fields (4)
  • active Boolean
    default=True
  • company_id Many2one → res.company
    args: 'res.company'
  • name Char
    required=True translate=True
  • rescheduled Boolean
    default=False help='If checked, checkpoints with this incident type will be rescheduled'
Public methods (0)

No public methods.

New fields (1)
  • partner_id Many2one → res.partner
    help='Partner for this visit window' ondelete='cascade' required=True string='Partner' args: 'res.partner'
Public methods (0)

No public methods.

New fields (10)
  • checkpoint_ids One2many → route.checkpoint
    args: 'route.checkpoint', 'route_id'
  • company_id Many2one → res.company
    default=<expr> required=True tracking=True args: 'res.company'
  • name Char
    copy=False default=<expr> readonly=True required=True
  • route_area_id Many2one → route.area
    ondelete='restrict' required=True tracking=True args: 'route.area'
  • schedule_date Date
    default=fields.Date.context_today required=True tracking=True
  • start_location_id Many2one → res.partner
    comodel_name='res.partner' default=<expr> tracking=True
  • state Selection
    compute='_compute_state' store=True tracking=True args: [('draft', 'Draft'), ('planned', 'Planned'), ('in_progress', 'In Progress'), ('done', 'Done')]
  • time_start Float
    compute='_compute_time_start' precompute=True readonly=False store=True tracking=True
  • user_id Many2one → res.users
    compute='_compute_user_id' precompute=True readonly=False store=True tracking=True args: 'res.users'
  • waiting_time Float
    compute='_compute_waiting_time' help='Average waiting time at each stop, expressed in minutes.' precompute=True readonly=False store=True tracking=True
Public methods (7)
  • action_draft(self)
  • action_open_google_maps(self)
  • action_planned(self)
  • action_view_map(self)
  • create(self, vals_list)
    @api.model_create_multi
    Override to set sequence and add user as follower
  • message_subscribe(self, partner_ids=None, subtype_ids=None)
  • write(self, vals)

New fields (3)
  • day_of_week Selection
    required=True args: [('0', 'Monday'), ('1', 'Tuesday'), ('2', 'Wednesday'), ('3', 'Thursday'), ('4', 'Friday'), ('5', 'Saturday'), ('6', 'Sunday')]
  • time_from Float
    help='Start time of the visit window'
  • time_to Float
    default=24.0 help='End time of the visit window'
Public methods (0)

No public methods.

New fields (3)
  • active Boolean
    default=True
  • line_ids One2many → route.visitwindow.template.line
    comodel_name='route.visitwindow.template.line' copy=True inverse_name='template_id'
  • name Char
    required=True
Public methods (0)

No public methods.

New fields (1)
  • template_id Many2one → route.visitwindow.template
    comodel_name='route.visitwindow.template' ondelete='cascade' required=True
Public methods (0)

No public methods.