Skip to content

sr_scheduling — Programmer's Notes

Module version: 17.0.1.0.0 Last updated: 2026-04-05 Primary owner: Dan Dependencies: sr_management, sr_management_fixes, base_geolocalize, crm, hr, hr_holidays


What This Module Does

Truck route scheduling and dispatch management. CSRs schedule pickups via the Add Note wizard — system finds the best date/route based on truck capacity, available hours, driving direction, and customer service windows. Includes driver messaging, LTL (less-than-truckload) pickups, and ORS (OpenRouteService) truck routing.

Downstream Dependents

Module What it uses
sr_truck_schedule truck.schedule model, calendar/task fields
sr_reports customer.pickups queries
sr_seo_locations sr_management + sr_scheduling fields

Key Models

Model Purpose
truck.schedule Route management (draft→in_progress→completed→cancel)
customer.pickups (inherited) Extends with truck assignment, service window enforcement
truck.route.log Warehouse departure/arrival tracking
ltl.pickup LTL freight pickup management
driver.message Driver-dispatcher two-way messaging
trucking.company LTL carrier info
ors.routing OpenRouteService truck routing (driving-hgv profile)

Critical Methods

customer_pickups.py

  • create() override calls _manage_truck_schedule() which uses ORS truck routing API
  • Set is_old_pickup=True to bypass route management in scripts/tests
  • _check_service_window_fits() — enforces customer HOO windows. Windows < 6 hours = "tight" constraint. Returns False if pickup doesn't fit.

ors_routing.py

  • All distances use driving-hgv (truck) profile, NOT car
  • API key in ir.config_parameter as ors_api_key
  • Falls back to haversine (35 mph, 1.3x winding factor) when ORS unavailable
  • Frontend maps proxy through /ors/route controller endpoint

Key Gotchas

  • Samsara route pushing is DISABLED — drivers use Odoo driver portal on tablets, not Samsara navigation
  • Samsara kept for: ELD, telemetry, mechanical notifications only
  • Timezone cron calls Google Maps API at 200/hour — first run on full DB takes ~24 hours
  • Service windows are separate from HOO (Apr 2026) — has_service_window / service_window_start / service_window_end on both res.partner and customer.pickups. HOO is just the customer's business hours (informational).
  • 0/0 HOO is allowed — means "not set yet" and won't raise ValidationError
  • Direction checking disabled (Apr 2026) — routing_utils.directions_are_compatible() always returns True. Route optimizer handles stop ordering; weight/time/box constraints prevent overloaded routes.
  • Stage writes trigger route recalculation hooks — be careful writing to pickup stage fields
  • morning_prep_minutes / evening_unload_minutes are region-specific — Sunbright 30min, others 60min
  • The Add Note wizard is the primary entry point for CSRs. It lives in wizard/add_note.py.
  • Wizard searches all trucks in region (Apr 2026) — not just the customer's default truck. Auto-updates truck_assigned_id when matching schedule found on different truck.

Route Time Estimation (Apr 2026)

The old truck.schedule.total_trip_time stored field summed per-pickup warehouse travel time (broken — treated each pickup as independent round-trip).

New method: truck.schedule.estimate_optimized_route_hours(extra_customer=None, extra_additional_time=0.0) - Nearest-neighbor TSP from warehouse → stops → warehouse - Haversine distance × 1.3 circuity factor (straight-line → road distance) - 50 mph average (East TN mix of mountain roads and interstate) - Plus stop times per pickup (time_at_pickup_location + additional_time)

Used in: customer.pickups._check_schedule_has_capacity, add.note._return_valid_schedules, res.partner.action_refresh_pick_up_date, add.note._build_schedule_explanation.

Stop Sequence Optimization (Apr 2026)

customer.pickups._optimize_schedule_sequence(schedule) runs on every pickup create/assign. Nearest-neighbor from warehouse writes sequence field on each pickup so the route displays in driving order.

System Parameters

Key Default Purpose
google_maps_api_key (required) Timezone lookup
ors_api_key (required) Truck routing
time_at_pickup_location 0.5 Hours per pickup stop
no_hours_per_day 10 Max route hours
trip_start_time 8.0 Default departure time
minimum_route_weight 1500 lbs — routes below this defer 7 days for consolidation
max_weight 8000 lbs — absolute max per route
max_number_of_boxes 50 max boxes per route
direction_scheduling.strictness relaxed legacy — no longer enforced (always compatible)
direction_scheduling.proximity_miles 100 legacy — no longer used

Testing

Scenario test harness: sr_scheduling/tests/run_scenarios.py (also on Dan's Desktop at ~/Desktop/scheduling_tests/)

Runs end-to-end scheduling scenarios from a CSV file, generates HTML report with color-coded pass/fail and optimized route summaries. Run with:

python3 ~/SR-Odoo/sr_scheduling/tests/run_scenarios.py

Functional tests: ~/Desktop/scheduling_tests/run_functional_tests.py — verifies module health (fields exist, methods callable, system params set).

Functional test spec: SR-Odoo/FUNCTIONAL_TESTS_SCHEDULING.md — full suite documentation.