Route Management¶
Bizwiz Module Guide — Sales & Revenue book, Chapter 05 Owns the "Route Manager" nav area under Sales & Receivables.
1. Purpose (plain language)¶
In Bizwiz, a route is the fundamental unit of the sales-and-delivery operation. It represents a geographic beat that a salesman/route rep works: a named territory (e.g. "Nakuru Town CBD") with a starting/loading point, a set of delivery centres (drop points), the customers/shops that live on it, targets (sales, tonnage, cartons, dozens), and the people assigned to it (salesman, route manager, supervisor, representative).
This chapter covers how routes are defined, listed, changed, geo-mapped, grouped, assigned to teams, and how visits along them are tracked. Concretely, the Route Manager area lets an admin:
- Define & list routes — create a route, set whether it is a physical/POS/offsite route, set targets, loading location, order-taking days and order frequency, and attach external "integration codes" for third-party systems.
- Break a route into structure — a route is made of sections (leg-by-leg segments between shops, each with distance/fuel/time estimates including rainy-weather variants), optional route plans (delivery-centre visit sequences with durations), and polylines (the drawn map path).
- Handle route change requests — field staff (via the mobile app) request changes to a route's details (e.g. reassign the route manager, supervisor, or representative). Office staff review these as pending → approved / declined, with an actioned history.
- Manage delivery centres and their integration codes (external system identifiers), individually or in bulk.
- Group routes into route groups and assign group representatives.
- Geo-map routes — schedule geomapping tasks so field staff walk/verify the route, capture customer serve-times, geotag customers, and produce a summary that can be marked complete and HQ-approved.
- Track route visits — how many customers were met with an order, met without an order, or unmet, feeding route-performance reporting.
- Assign routes to teams and set field-visit schedules and route shift overrides.
Boundary notes (owned elsewhere, referenced here):
- The customer record & credit lifecycle lives in Customer Management; this chapter owns route structure, geomapping, and visit scheduling. (Geotagging of customers straddles the two — see §5.)
- Vehicle geofencing / route-compliance monitoring lives in the Fleet & Logistics book. RouteDeviationAlert is created in DeliveryScheduleController, not in this module — see §5/§7.
- Salesman/deliveryman shift execution against a route lives in Order Taking / Dispatch & Delivery.
2. Users & roles¶
Access spine. All Route Manager nav visibility keys off two things (see resources/views/admin/includes/sidebar_includes/sales_and_receivables.blade.php):
1. $logged_user_info->role_id == config('app.allowed_role') (the super-admin / allowed role), OR
2. a permission key such as route-manager___view, route-groups___view, delivery-centre-integration-codes___view, etc.
Permissions are enforced in controllers via the global can($action, $module) helper (app/helpers.php:4182), which returns true if the user's permission map contains "{module}___{action}", or if the user is role_id == 1 (treated as superadmin, all permissions). Examples in code:
- RouteController@listing → can('view', 'route-manager') (app/Http/Controllers/Admin/RouteController.php:105)
- RouteController@create → can('add', 'routes') (:244)
- RouteController@updateRouteIntegrationCodes → can('edit', 'routes') (:965)
- RouteController@routeTonnageSummary → can('download-report', 'manage-routes') (:129)
- GeotaggedCustomerRequestsController@index → can('geotagged-approval-requests', 'route-customers') (app/Http/Controllers/Admin/GeotaggedCustomerRequestsController.php:38)
Permission catalogue. The permission tree is declared in app/Permissions/SalesAndReceivables.php under the "Route Manager" node (:88), which owns child models:
- route-manager (view) — Route Listing (:94)
- delivery-centre-integration-codes (view, edit) (:100)
- route-groups (view, add-group, edit-group, delete-group) (:107)
- route-customers (view/add/edit/remove/verify/approve/edit-pin) plus child actions: onboarding-requests, approval-requests, duplicate-approval-requests, geotagged-approval-requests, field-visits, geomapping-schedules, edit-schedule, shedule-delete (sic — misspelled in code), geomapping-summary, geomapping-comments (:116–:209)
Route Manager also appears in app/Permissions/SystemAdministration.php:441.
Roles that show up in route logic:
- Salesman — role_id == 4 (Route::salesman(), app/Model/Route.php:93).
- Route Manager — matched by role slug route-manager (Route::routeManagerUser()/routeManager(), app/Model/Route.php:106,118); the route also caches a route_manager_id.
- Supervisor / Representative — RouteSupervisors / RouteRepresentatives records per route (app/Model/Route.php:211–229), with currentSupervisor/currentRepresentative = latestOfMany().
- Chief dispatcher — Route::dispatcher() (:111).
⚠️
hasRouteManagerAccess()does not exist in the codebase. A repo-wide grep forhasRouteManagerAccess/RouteManagerAccess/route_manager_accessreturns no matches. The prompt asked us to note this helper; in practice access is gated bycan('view','route-manager')and the sidebar'srole_id == config('app.allowed_role')/route-manager___viewchecks. Flagged in §7.
3. Processes¶
3.1 Route definition (create → structure)¶
Nav: Route Manager → Route Listing → manage-routes.index (RouteController@index, listing view admin.routes.index_new). The older listing action RouteController@listing (:103) renders admin.routes.index and is gated by can('view','route-manager').
Create flow (RouteController@create → store, app/Http/Controllers/Admin/RouteController.php:242–361):
flowchart TD
A[Route Manager → Route Listing] --> B[Create Route form<br/>admin.routes.create]
B --> C{is_physical_route?}
C -->|1 physical| D[Require starting_location_name,<br/>loading lat/lng; set targets,<br/>order_taking_days, order_frequency,<br/>fuel/travel/shift fields]
C -->|0 non-physical| E[Store name/branch/flags only]
D --> F[Route::create + Route::update]
E --> F
F --> G{SHOW_ROUTE_INTEGRATION_CODES on?}
G -->|yes| H[WaRouteIntegrationCodeService::replaceAll<br/>attach external route codes]
G -->|no| I[commit]
H --> I
I --> J[Route exists]
J --> K[Add sections / route plan / polylines<br/>+ delivery centres + customers]
Key route flags set at creation (:305–337): is_physical_route, is_pos_route, is_offsite_route, allow_re_geomapping, allow_bluetooth_printing, group, order_frequency, start/end_monthly_order_frequency (parsed from "X to Y" strings), starting_location_name, start_lat/start_lng, targets (tonnage_target, sales_target, ctn_target, dzn_target), manual_fuel_estimate, travel_expense, salesman_proximity/route_manager_proximity, offsite_shift_allowance, maximum_allowed_shifts, estimated_shift_time.
The route → centre → customer hierarchy:
flowchart TD
R[Route<br/>routes table] -->|hasMany centers| DC[DeliveryCentres<br/>drop points, lat/lng]
R -->|hasMany sections| SEC[RouteSection<br/>legs w/ distance/fuel/time,<br/>+ rainy variants]
R -->|hasMany polylines| PL[RoutePolyline<br/>drawn map path]
R -->|hasMany waRouteCustomer| WC[WaRouteCustomer<br/>shops on the route]
R -->|hasMany routePlanCenter?| RP[RoutePlan<br/>visit sequence + timings]
RP -->|hasMany| RPC[RoutePlanCentre<br/>centre + duration]
DC -->|hasMany| RPC
DC -->|hasMany| DCI[DeliveryCentreIntegrationCode]
R -->|hasMany| RI[WaRouteIntegrationCode]
- Sections are edited via
RouteController@updateSections(:1860, routemanage-routes.sections.update), which updates eachRouteSection'sfuel_estimate,distance_estimate,time_estimate,road_condition,road_typeplus therainy_*equivalents. - Route plans (
RoutePlanController) let you define, per route, a sequence of delivery centres with adurationeach, plustotal_distance/total_time/total_fuelandstart_time/end_time(RoutePlanController@store,app/Http/Controllers/Admin/RoutePlanController.php:85). Edit replaces allRoutePlanCentrerows (:201). - Route master plans (
RouteMasterPlanController) are a separate, newer plan concept (/routes/{id}/plan,routes/web.php:3529–3532) writingstart_location_name/latitude/longitudeand per-segment estimates via$route->routePlan(). This appears incomplete — there is noroute_master_planmigration and noroutePlan()relation onRoute; see §6/§7.
3.2 Route change request → approval¶
Requests are created from the mobile app, not the web UI: routes/modules/api.php:562 → RouteController@storeRouteChangeRequest (:996). The office side reviews them under Route Manager → Route Change Requests (routes/web.php:4689–4698, prefix route-change-requests.).
flowchart TD
subgraph Mobile
A[Field staff proposes changes] --> B[POST /store-route-change-request<br/>storeRouteChangeRequest]
end
B --> C[RouteChangeRequests row<br/>status = pending<br/>changes = JSON diff<br/>requested_by]
C --> D[Pending list<br/>showPendingRouteChangeRequests]
D --> E[View details<br/>showPendingRouteChangeRequestDetails]
E --> F{Reviewer decision}
F -->|Approve| G[approveRouteDetailsChangeRequest]
F -->|Decline| H[declineRouteDetailsChangeRequest]
G --> I[convertToUpdateArray:<br/>split direct vs relationship changes]
I --> J[route->update direct fields]
I --> K[relationships: supervisors /<br/>representative / route_manager<br/>rewrite pivots + *_id]
J --> L[status = approved,<br/>approved_by, approved_at]
K --> L
H --> M[status = declined,<br/>declined_by, decline_reason, decline_at]
L --> N[Approved list + History]
M --> O[Declined list + History]
- Status field on
route_change_requests:pending→approved|declined. Set toapprovedatRouteController.php:1278; declined analogously indeclineRouteDetailsChangeRequest(:1374). - Applying an approval (
approveRouteDetailsChangeRequest,:1176): decodeschangesJSON, callsconvertToUpdateArray()(:1311) to separate direct route-column updates from relationship updates. Relationship handlers: supervisors→ delete + recreateRouteSupervisors, setroute->supervisor_idto the last (:1213).representative→ delete + recreateRouteRepresentatives(:1231).route_manager→ validate viaRouteUserAssignmentService, upsert theroute_userpivot, setroute->route_manager_id(:1244).- List/history views: pending (
:1025), approved (:1421), declined (:1467), actioned history (:1513), each with a matching datatable endpoint (:1078,:1553,:1616,:1680). - Approve/decline are also exposed on the mobile API (
routes/modules/api.php:563–564).
3.3 Geomapping / geotagging¶
There are two generations of geomapping (see §6):
- Geomapping (schedules/summary — "v1"):
resource('geomapping-schedules', GeomappingSchedulesController)(routes/web.php:5380) plusgeomapping-summary(:5382),summaryShow(:5383),markScheduleAsComplete(:5384),markScheduleAsHQApproved(:5385), andcustomerServeTime(:5381). Flow: create a schedule → field staff geomap → view summary → mark complete → HQ approve. Models:GeomappingSchedules, plusGeomappingScheduleExecution(deletable viadeleteExecution,:5102). - Geomapping tasks ("v2"):
GeomappingTasksController(routes/web.php:5078–5102, prefixgeomapping/schedules). Richer model: a schedule has ordered tasks (createTask,updateTask,moveTaskUp/Down) and attached routes (attachRoute/detachRoute,apiRouteSchedules); executing a schedule produces executions with responses and an uploadable KML overlay (uploadKml/viewKml,:5100). Reports:responsesReport(:5098),executionDetail(:5099).scheduleRouteVisit(:5088) schedules a route visit against a geomapping schedule. The sidebar also surfacesroute-customers-geomapping-v2andgeomapping-tasks-report. - Geotagging = approving field-captured GPS locations for route customers.
GeotaggedCustomerRequestsController(routes/web.php:6008–6013) listsWaRouteCustomerrecords withstatus == 'geotagged'(GeotaggedCustomerRequestsController.php:54) and lets a reviewerapprove/reject/approveAll. (The customer record is owned by Customer Management; this module owns the geotag approval workflow tied to the route.)
3.4 Route visit tracking¶
Route performance is reported as met-with-order / met-without-order / unmet customer counts. RoutePerformanceReportController@unmetCustomers (routes/web.php:5619, sales-and-receivables-reports.unmet-customers) reports customers on a route that were not met. Chair-level rollups exist too (ChairSalesReportController@getMonthlyMetUnmetData, routes/web.php:451). Visit locations feed off OrderLocationLog / geomapping serve-times. (Exact met/unmet computation not fully traced — see §7.)
4. Tables touched & key data¶
| Table | Model | Purpose / key columns |
|---|---|---|
routes |
App\Model\Route (app/Model/Route.php) |
Master route. $guarded=[]; soft-deletes; sluggable on route_name. Cols incl. route_name, restaurant_id (branch), is_physical_route, is_pos_route, is_offsite_route, allow_re_geomapping, allow_bluetooth_printing, group, order_frequency, start/end_monthly_order_frequency, starting_location_name, start_lat/lng, targets (tonnage_target, sales_target, ctn_target, dzn_target), manual_fuel_estimate, travel_expense, salesman_proximity, route_manager_proximity, offsite_shift_allowance, maximum_allowed_shifts, estimated_shift_time, supervisor_id, route_manager_id, default_wa_route_customer_id. |
route_sections |
App\RouteSection |
Legs between shops. route_id, start_shop_id/end_shop_id, start/end lat/lng, start_point_is_plan_start_point, fuel_estimate (L), distance_estimate (km), time_estimate (min), road_condition, road_type, + rainy_* variants (migration 2023_09_16_090112 + 2023_10_23_162058). |
route_polylines |
App\RoutePolyline |
Drawn path. route_id, polyline (longText), waypoint_order, lat_lngs (longText; migration 2023_11_24_105626 + 2023_12_15_104319). |
route_plans |
App\RoutePlan |
Route delivery plan. route_id, start/end lat/lng, total_distance/time/fuel, start_time, end_time. |
route_plan_centres |
App\RoutePlanCentre |
Plan ↔ centre with duration. route_plan_id, delivery_centre_id, duration. |
route_master_plans (missing?) |
App\RouteMasterPlan |
$guarded=[]; hasMany RouteMasterPlanSegment. No migration found — see §7. |
route_master_plan_segments (missing?) |
App\RouteMasterPlanSegment |
Per-segment estimates. No migration found. |
delivery_centres |
App\Model\DeliveryCentres |
Drop points. $guarded=[]; soft-deletes; route_id, lat/lng (cast float), preferred_center_radius (default 1000). hasMany DeliveryCentreIntegrationCode, WaRouteCustomer. |
delivery_centre_integration_codes |
App\Model\DeliveryCentreIntegrationCode |
External codes per centre. |
wa_route_integration_codes |
App\Models\WaRouteIntegrationCode |
External route codes; managed by WaRouteIntegrationCodeService; restaurant_id auto-synced on route save (Route::booted, app/Model/Route.php:249). |
route_change_requests |
App\Models\RouteChangeRequests |
route_id, changes (JSON diff), status (pending/approved/declined), requested_by, approved_by, declined_by, decline_reason, decline_at, approved_at. |
route_supervisors |
App\Models\RouteSupervisors |
Per-route supervisor assignments (route_id, user_id, created_by). |
route_representatives |
App\Models\RouteRepresentatives |
Per-route representative assignments. |
route_user (pivot) |
— | Route ↔ User (salesman/route-manager) many-to-many. |
route_vehicle (pivot) |
— | Route ↔ Vehicle (whitelist/blacklist logic, Route::allowedVehicles). |
route_shift_overrides |
App\RouteShiftOverride |
Per-route shift overrides (migration 2026_03_12_100000). (See §7 for semantics.) |
route_deviation_alerts |
App\RouteDeviationAlert |
Deviation alerts (migration 2023_12_18_153703). Created by DeliveryScheduleController — Fleet/Dispatch owned; see §5/§7. |
| geomapping tables | GeomappingSchedules, GeomappingRouteSchedule, GeomappingScheduleExecution, GeomappingScheduleTask, GeomappingTaskResponse, GeomappingTaskField, GeomappingTaskResponseField, GeomappingExecutionKml, GeomappingTaskSchedule (all app/Models/) |
v1 summary + v2 task/execution/response model. (Column-level detail partially traced — see §7.) |
| team tables | App\Team, App\TeamMember, App\TeamRoute |
Teams, members, and their assigned routes. (See §7.) |
field_visit_schedules |
App\FieldVisitSchedule |
Field visit scheduling (resource field-visits). (See §7.) |
| route group tables | App\Models\SalesRoutesGroup, SalesGroupRoute, SalesRoutesGroupLog |
Route groups, group↔route pivot, change log. (See §7.) |
5. Interactions with other modules¶
- Customer Management — routes hold
WaRouteCustomershops; geotagging approves customer GPS (status='geotagged'onWaRouteCustomer). The customer record/credit lifecycle is owned there; this module owns which route a customer sits on and the geotag approval workflow. - Order Taking —
is_pos_route/is_physical_route/is_offsite_routeand order-taking days/frequency drive how salesmen take orders on a route;SalesOrderController@getRoutesByRouteGroup(routes/web.php:1416) resolves routes for order entry. Shift execution against a route (SalesmanShift,app/Model/Route.php:154,244) is owned by Order Taking. - Dispatch & Delivery / Fleet & Logistics —
DeliverySchedule/delivery_schedule_routeslink routes to dispatch runs (app/Model/Route.php:200–209).Route::allowedVehicles()(:162) resolves whitelisted/blacklisted vehicles per route.RouteDeviationAlertis created inDeliveryScheduleController— vehicle deviation/geofencing is Fleet-owned; this module only defines the route the vehicle is measured against. - HR / Employees — role slugs
route-manager,salesman(role_id 4),chief-dispatcher, and theroute_userpivot connect employees to routes;RouteUserAssignmentServicevalidates assignments. - Reporting — route targets and visits feed
RouteController@routeTonnageSummary,RoutePerformanceReportController, chair sales rollups. Report controllers (route daily/weekly/performance/return-summary) are separate report chapters but read this module's route structure. - System settings —
Settingslugshow-route-integration-codes(see §6) gates integration-code UI across routes, delivery centres, and locations/stores.
6. Alternatives & variants¶
SHOW_ROUTE_INTEGRATION_CODESsetting (database/seeds/SettingsSeeder.php:294; slugshow-route-integration-codes, type boolean, CLIENT-MANAGED, default0). When off, integration-code inputs are hidden/blocked in five places that share the identical checkSetting::where('slug','show-route-integration-codes')->value('description'):RouteController@routeIntegrationCodeInputsEnabled(:988) — gates create/edit route codes;updateRouteIntegrationCodesabort(403)if off (:970).DeliveryCentreIntegrationCodesController(:22),BulkRouteIntegrationCodesController(:23),BulkDeliveryCentreIntegrationCodesController(:23),LocationAndStoreController(:328). Sidebar visibility mirrors this viasetting('SHOW_ROUTE_INTEGRATION_CODES', false)(sidebar…blade.php:440,2096,2104). A per-flavor toggle — only clients that integrate with external systems turn it on.- Geomapping v1 vs v2. v1 =
GeomappingSchedulesController(schedules + summary + mark-complete + HQ-approve). v2 =GeomappingTasksController(ordered tasks, route attachment, executions, task responses, KML upload) surfaced in the sidebar asroute-customers-geomapping-v2/geomapping-tasks-report. Both are wired; v2 is the richer, newer flow. Likely coexist per flavor. - Route "plan" concepts overlap. Three plan mechanisms exist:
RoutePlan/RoutePlanCentre(working, centre-sequence + durations), section-level estimates onRouteSection, andRouteMasterPlan/RouteMasterPlanSegment(routes wired atweb.php:3529–3532but no matching migration and noRoute::routePlan()relation) — the master-plan feature looks incomplete or dead. Confirm in §7. - Duplicate
" 2.php"files = cruft.app/RouteMasterPlan 2.php,app/RouteMasterPlanSegment 2.php, andapp/Http/Controllers/Admin/RouteMasterPlanController 2.phpare byte-identical copies of their canonical counterparts (verified viadiff). They are not autoloaded (space in filename → invalid class path) and should be treated as accidental copies to delete. RouteManagerControllerexists but is unrouted.app/Http/Controllers/Admin/RouteManagerController.phpis not referenced by any route file — the live route listing isRouteController(manage-routes.*). Likely legacy.- Route flags create behavioral variants:
is_physical_route(0 → skips targets/location/salesman logic; shown as "N/A" in tonnage summary,RouteController.php:153),is_pos_route,is_offsite_route("Fully Offsite"),allow_re_geomapping,allow_bluetooth_printing(further gated by branchactivate_bluetooth_printing,app/Model/Route.php:263). - Branch scoping. Non-admins see only their branch's routes unless they hold
route-manager___view-all-routesoremployees___view_all_branches_data(RouteController@index:87,datatable:181,listing:119). .bakroute file.routes/modules/sales_and_receivables.php.bakexists alongside the live file — stale backup, ignore.
7. Open questions to confirm¶
hasRouteManagerAccess()— the prompt referenced this helper, but it does not exist anywhere in the codebase (confirmed by grep). Confirm whether it once existed and was replaced bycan('view','route-manager'), or whether it's a naming assumption. (High confidence it's absent.)RouteMasterPlanfeature status — routes exist (web.php:3529–3532) and models exist, but there is noroute_master_plan(_segments)migration and noroutePlan()relation onRoute(grep found none). Is this dead/half-built, or is the table/relation created elsewhere (raw SQL, another connection)? Live calls would error.- Duplicate
" 2.php"files — confirmed identical; confirm they can be safely deleted (assumed yes). - Route visit met/unmet computation — I confirmed the reporting surface (
RoutePerformanceReportController@unmetCustomers, chair met/unmet rollup) and the presence ofOrderLocationLog, but did not fully trace how "met with order / met without order / unmet" is computed (which table/joins, order-vs-visit correlation). Needs a dedicated trace. - Geomapping table columns — v1/v2 model set enumerated, but per-column schema for
geomapping_*tables was only partially traced. Confirm the execution → response → field data model and how KML overlays attach. - Teams, field-visit schedules, route shift overrides — controllers and models identified (
TeamController/Team/TeamMember/TeamRoute,FieldVisitController/FieldVisitSchedule,RouteShiftOverrideController/RouteShiftOverride) but their exact fields, create flows, and runtime semantics (esp. what a "shift override" overrides, and how field-visit schedules differ from geomapping schedules) were not fully read. Needs confirmation. - Route groups & group representatives —
SalesRoutesGroupsController/SalesRoutesGroup/SalesGroupRoute/SalesRoutesGroupLogandGroupRepresentativeController/RouteRepresentativesidentified; confirm how a "group representative" (add_route/ressign_route/ressign_all_routes,routes/modules/sales_and_receivables.php:522–524) differs from a per-routeRouteRepresentativesrecord. RouteDeviationAlertownership — created inDeliveryScheduleController; confirm the exact trigger and whether any Route-Manager UI reads these alerts (the boundary with Fleet's vehicle-tracking compliance).RouteManagerController— confirm it is truly dead/unrouted legacy.
8. Source references¶
Nav / IA
- resources/views/admin/includes/sidebar_includes/sales_and_receivables.blade.php — Route Manager, Route Customers, Geomapping, integration-code visibility (:9, :112–147, :178–260, :440, :2096, :2104).
Routes
- routes/web.php — route plans (:3516–3520), master plan (:3529–3532), manage-routes resource + sections/integration (:4679–4686), route change requests (:4689–4698), delivery-centre integration codes (:4704–4728), geomapping v2 (:5078–5102), route-shift-overrides (:5373), field-visits (:5378), geomapping-schedules/summary (:5380–5385), route merge/duplicate (:4440–4447), teams (:5437), geotagged customers (:6008–6013), unmet customers report (:5619).
- routes/modules/api.php:560–564 — mobile route store/update and change-request store/approve/decline.
- routes/modules/sales_and_receivables.php:519–524 — group representative.
Controllers (app/Http/Controllers/Admin/)
- RouteController.php — listing/create/store/update (:69,:103,:242,:274,:363), integration codes (:963,:988), change-request store/list/approve/decline (:996,:1025,:1176,:1374,:1421,:1467,:1513), sections (:1860), map/polyline helpers (:493,:540,:580).
- RoutePlanController.php, RouteMasterPlanController.php, DeliveryCentresController (via web.php:3515,3522), DeliveryCentreIntegrationCodesController.php, GeomappingSchedulesController.php, GeomappingTasksController.php, GeotaggedCustomerRequestsController.php (:38,:54), FieldVisitController.php, RouteShiftOverrideController.php, TeamController.php, SalesRoutesGroupsController.php, GroupRepresentativeController.php, RouteMergingController.php, RouteDuplicationController.php, RoutePerformanceReportController.php.
- Unrouted/legacy: RouteManagerController.php.
Models
- app/Model/Route.php, app/Model/DeliveryCentres.php, app/Model/DeliveryCentreIntegrationCode.php, app/Model/Route*.php.
- app/RoutePlan.php, app/RoutePlanCentre.php, app/RouteSection.php, app/RoutePolyline.php, app/RouteMasterPlan.php, app/RouteMasterPlanSegment.php, app/RouteShiftOverride.php, app/RouteDeviationAlert.php, app/Team.php, app/TeamMember.php, app/TeamRoute.php, app/FieldVisitSchedule.php, app/OrderLocationLog.php.
- app/Models/RouteChangeRequests.php, RouteRepresentatives.php, RouteSupervisors.php, SalesRoutesGroup.php, SalesGroupRoute.php, SalesRoutesGroupLog.php, WaRouteIntegrationCode.php, and the Geomapping* set.
- Cruft: app/RouteMasterPlan 2.php, app/RouteMasterPlanSegment 2.php, app/Http/Controllers/Admin/RouteMasterPlanController 2.php.
Migrations (database/migrations/)
- 2023_09_16_090112_create_route_sections_table.php (+ 2023_10_23_162058_add_weather_routes_to_route_sections.php)
- 2023_11_24_105626_create_route_polylines_table.php (+ 2023_12_15_104319_add_latlngs_to_route_polylines.php)
- 2023_12_18_153703_create_route_deviation_alerts_table.php
- 2026_03_12_100000_create_route_shift_overrides_table.php
Settings / permissions / helpers
- database/seeds/SettingsSeeder.php:294 (SHOW_ROUTE_INTEGRATION_CODES).
- app/Permissions/SalesAndReceivables.php:88–209; app/Permissions/SystemAdministration.php:441.
- app/helpers.php:4182 (can()); getUserPermissions().