Skip to content
TAQNIX
Odoo ModulesWordPress PluginsWordPress ThemesShopify ThemesApp TemplatesScripts & UtilitiesBlogSell on TAQNIX

Odoo Field Service Management documentation

A guide to Odoo Field Service Management: installing the module, configuring dispatch, offers, tracking, timesheets, van stock and invoicing, and building, publishing and using the technician app.

Documents version 1.0.0Updated Oct 29, 2026

Start here

In plain words: This package gives you a complete field service system for Odoo Community: an Odoo module (taqnix_fsm) for the office, and the Flutter source code of the iPhone and Android app your technicians use on the road, even without a network. The office plans and dispatches the jobs, follows the technicians on a map, and invoices the work; the technician accepts a job, drives to the customer, works with a timer, scans the parts used, takes photos, collects the signature and sends the invoice from the phone.
The dispatch map: technicians, jobs and the jobs waiting to be assigned.
The dispatch map: technicians, jobs and the jobs waiting to be assigned.
Tip: You do not need Odoo Enterprise: the module uses only the free apps Project, Timesheets, Inventory and Invoicing, and OpenStreetMap for the maps (no paid map key).

What is in the package

ItemWhat it is
taqnix_fsm.zipThe Odoo 19 module: orders, dispatch, offers, live map, geofence, timer and timesheets, van stock, signature and photos, billing, push notifications, the API of the app, Arabic translation, automated tests.
flutter-app-source.zipThe Flutter project of the technician app (Android and iOS): offline database, sync engine, background location, barcode scanner, signature pad, photos, invoice. With a setup script, its own README and tests.
documentation/This guide in English (index.html) and Arabic (index-ar.html), with PDFs, and API.md for developers.
licensing/The licence (OPL-1: one purchase = one company and one app brand, updates included).
preview-images/Screenshots of the app and of the Odoo screens.
changelog.txtHistory of the versions.

How it works

PartWhere it runsWhat it does
Odoo moduleYour Odoo serverKeeps orders, technicians, time, parts, photos, signatures and invoices; decides who is offered a job; answers the app on /api/fsm/v1/....
Dispatch mapThe browser of the dispatcherShows technicians and jobs on OpenStreetMap, refreshes by itself, draws the route of the day.
Technician appThe phones of your techniciansWorks from a local database (SQLite). Everything the technician does is stored on the phone first and sent when there is a network.
Firebase (optional)GoogleDelivers push notifications: new job, job offered, job changed or cancelled.
In plain words: A job goes through these steps: New → Assigned → On the way → (Arrived) → In progress → (On hold) → Completed. Every step is stamped with the GPS position and the time of the phone, and these stamps cannot be edited afterwards. At the end Odoo books the timesheet, moves the parts out of the stock of the van, and prepares the invoice.

What you need

ItemDetails
Odoo19.0 Community or Enterprise. The apps Project, Timesheets, Inventory, Invoicing and Contacts geolocation are installed automatically with the module.
Python librariesPyJWT and requests (push notifications). pip install PyJWT requests if your Odoo does not have them.
PDF enginewkhtmltopdf as for any Odoo (service report and invoice PDF).
AddressA public https address for your Odoo: the phones must reach it. A self-signed certificate does not work on phones.
Outgoing emailAn outgoing mail server in Odoo (Settings → Technical → Outgoing Mail Servers) to email invoices and reports.
A computer to build the appA Mac for iPhone and Android (Windows or Linux can build Android only), about 30 GB free.
Developer toolsFlutter 3.41 or newer, Android Studio and Xcode (current versions) with CocoaPods.
Store accountsGoogle Play Console (one-time fee) and Apple Developer Program (yearly fee). You can also distribute to your own staff without the public stores (internal testing, TestFlight, Apple Business Manager).
OptionalA free Firebase project for push notifications.

Install the Odoo module

  1. Unzip the package. Inside is taqnix_fsm.zip; unzip it to get the folder taqnix_fsm.
  2. Copy the folder into one of the addons_path folders of your Odoo server and restart Odoo.
  3. Log in as an administrator, activate Developer mode, open Apps and press Update Apps List.
  4. Remove the “Apps” filter, search Field Service Management and press Install.
# or from the command line
./odoo-bin -c odoo.conf -d YOUR_DATABASE -i taqnix_fsm --stop-after-init
In plain words: After the installation a new app Field Service appears in the main menu. The installation also creates a Field Service project (for the timesheets), the products Field service labor, Callout fee and Travel, six service types, skills, checklists, hold reasons and the mail templates. You can change or delete all of them.
Important: Take a backup before installing on a production database, as for any module.

First setup in 10 minutes

  1. Open Field Service → Configuration → Settings and walk through the sections (chapter 8). The defaults already fit most companies.
  2. Check the labor product and its price in Invoicing (Settings, chapter 8) and the callout and travel products.
  3. Create the technicians (chapter 7): an Odoo user, an employee for the timesheets, skills, a van stock location.
  4. Put the parts in the vans: a normal Inventory adjustment or transfer into the location of each van.
  5. Edit the service types to match your services: duration, price, checklist, proof required (chapter 9).
  6. Create the first order (chapter 10), dispatch it and try it in the app (chapters 13 and 14).
Tip: The defaults are neutral enough for HVAC, plumbing, electrical, IT, appliance repair, security and facility services. Chapter 8 ends with a table of recipes by industry.

Technicians, dispatchers and managers

In plain words: There are three groups in Settings → Users → Field Service:
GroupCanUses
TechnicianSign in to the mobile app, see their jobs and the jobs offered to them, do the work. In Odoo they see only their own orders.The phone
DispatcherCreate, assign and cancel orders, use the map, create and send invoices, see all orders, technicians and tracking.Odoo in the browser
ManagerEverything of the dispatcher plus the settings, service types, checklists, devices and the right to complete an order without the required proof.Odoo in the browser
In plain words: To add a technician, open Field Service → Technicians → Technicians and press New: choose the Odoo user (create it first in Settings → Users; it needs no other access right), the employee that receives the timesheets, the teams, the skills, the hourly billing rate (optional) and the van stock location. Press Create van location to create a location under the stock of your warehouse. The technician receives the group Technician automatically.
A technician: employee, teams, skills, van stock and status.
A technician: employee, teams, skills, van stock and status.
The list shows who is online, the battery and the open orders.
The list shows who is online, the battery and the open orders.
Tip: The Odoo login and password of the user are the ones used in the app. Give technicians a strong password; Sign out all devices on the technician form revokes every phone at once.

The settings, section by section

In plain words: Field Service → Configuration → Settings holds every rule of the company. Each block below says what it does and when to change it. Settings are per company.
Dispatch: who gets the jobs.
Dispatch: who gets the jobs.
SettingWhat it does
Default dispatchAssigned to a technician: the dispatcher picks one. Open to the team: every technician of the team (with the skills needed) sees the job and the first to accept gets it. Offered to nearby technicians: only technicians within the radius of the job, from their last position, nearest first. Can be changed per order.
Offer radius, technicians offered, expiry, roundsHow far, how many, how long an offer lasts (minutes) and how many rounds are tried. If nobody accepts, the radius is doubled (optional) and the job is offered again; after the last round the dispatcher gets a to-do.
Technicians can decline / give back a jobA technician may refuse an assigned job, or give it back before the work starts. It returns to the dispatcher (or to the offer).
Technicians can create ordersFor walk-in customers and extra work found on site: the technician creates an order from the phone, assigned to themselves.
Proof of work.
Proof of work.
SettingWhat it does
Customer signatureAn order cannot be completed without the signature (can be overridden per service type).
Photos before / afterAt least one photo of each kind is required.
ChecklistItems marked required on the checklist must be ticked.
Time to correct a completed orderThe technician can still add notes, parts and photos for this many hours after completing.
Location, tracking and arrival.
Location, tracking and arrival.
SettingWhat it does
Location trackingOff; Only while a job is under way (from On the way until Completed); During working hours (also when idle, so you can offer jobs to the nearest technician).
Battery friendly samplingInterval while moving (default 30 s) and while still (300 s), minimum distance between points (25 m), and the battery level under which the app samples less.
Arrival detection (geofence)Radius around the job (default 150 m) and the time the technician must stay inside (seconds). Then: Ask the technician (push + a prompt in the app), Mark as arrived, or Mark as arrived and start the work (starts the timer).
PrivacyThe text shown in the app before it asks for the location permission, and how many days the location points are kept (default 30).
Time and timesheets.
Time and timesheets.
SettingWhat it does
TimesheetsOn completion the worked time (without the pauses that stop the timer) is booked on the employee of the technician, on the task of the order. One line per order or one per work interval; optional rounding up (for example 15 minutes).
Project task per orderEvery order gets a task in the Field Service project, for timesheet reports and the Project app.
Warn when a technician has no employeeThe dispatcher gets a to-do when a timesheet could not be booked.
Parts and van stock.
Parts and van stock.
SettingWhat it does
When parts are usedValidate the stock moves: when the order is completed a transfer from the van to the customer is created and validated. Create the transfer to validate later: the transfer waits for a storekeeper. Do not move stock: only billing.
Parent of the van locationsNew van locations are created below this location.
Allow parts the van does not have / any productStrict mode: the technician can only use what is in the van.
Prices in the appShow the prices to the technician and, separately, let them change them.
Invoicing.
Invoicing.
SettingWhat it does
Default billingTime and materials, Fixed price or Materials only; the labor product and whether the hourly rate of the technician is used (chapter 15).
Duration based billingBill time in blocks (default 15 min), a minimum billable time (default 60 min) and minutes covered by the callout fee.
Callout and travelA fee per visit and a fee per kilometre beyond a free distance, measured from the recorded positions between On the way and Arrived.
Invoice creationManually, or automatically when the order is completed, optionally confirmed and emailed too.
Invoicing from the appWhat the technician may do on the phone: create the draft invoice, confirm it, email it to the customer.
Notifications.
Notifications.
SettingWhat it does
Push notificationsTo the technician: job assigned or changed, job offered, job cancelled.
Emails to the customerA message when the technician is on the way; the service report (PDF) when the work is completed.
FirebaseThe identifiers of your Firebase project and the service account JSON (chapter 17).
The dispatch map.
The dispatch map.
IndustrySuggested settings
HVAC and refrigerationService types: Repair (time and materials) and Preventive maintenance (fixed price with included minutes). Van stock strict, photo after required, checklist required, geofence prompt.
Plumbing and emergency repairDefault dispatch nearby, offer radius 15-25 km, tracking during working hours, callout fee and travel fee, geofence auto-arrived, no required photos.
ElectricalChecklist with a safety item (required), hold reason Safety issue, signature required, photos before and after.
IT and networkNo parts or few; time billing in blocks of 15 minutes, minimum 30; tracking on job only; signature required.
Appliance repairTime and materials, van stock, Warranty visit service type with materials only; photos before and after.
Security and CCTV installationFixed price per installation, photos after required, checklist with serial numbers noted.
Facility services and cleaningFixed price, checklist required, signature of the site manager, tracking on job only.
Medical and lab equipmentSignature always required, checklist required, Manager can complete without proof only for managers.

Service types, skills, checklists and hold reasons

In plain words: These lists describe your business. They live in Field Service → Configuration and are copied into every order, so changing them never alters old orders.
The service types that come with the module.
The service types that come with the module.
A service type: planned duration, skills, checklist, proof and billing.
A service type: planned duration, skills, checklist, proof and billing.
ListWhat to know
Service typesPlanned duration (used for the calendar), skills needed, a checklist, whether the signature and the photos are required (as in the settings, yes or no), billing mode, price, included minutes, hourly rate and callout fee. The app shows them with their color.
SkillsAttached to technicians and service types. With skills on the order only the qualified technicians are offered the job and ranked first in the assignment wizard.
ChecklistsTemplates of tasks; items marked required must be done before completion when the setting is on. The technician ticks them in the app and can add a note.
Hold reasonsOffered when a technician pauses a job (waiting for parts, customer not available, break...). Stops the timer decides whether the pause counts as worked time; Needs a note forces a comment.
Hold reasons.
Hold reasons.

Create and dispatch orders

In plain words: Field Service → Dispatch → Orders shows the orders as a board by status, a list, a calendar by technician, and pivot and graph reports.
The order board.
The order board.
The calendar: jobs by technician and day.
The calendar: jobs by technician and day.
  1. Press New and choose the customer. The service address, phone and the coordinates are taken from the customer; press Find to geolocate an address with OpenStreetMap, or open the Map tab and click the exact place.
  2. Choose the service type (it fills the duration, skills and checklist), the scheduled start, the priority, and write the description and the instructions for the technician (gate code, who to ask for, dangers).
  3. Choose how to dispatch: pick a technician, or leave it open to the team or to nearby technicians.
  4. Press Dispatch. A direct order becomes Assigned and the technician gets a push notification; an open order becomes Offered to the technicians that qualify.
An order in progress: customer, work, dispatch and the tabs.
An order in progress: customer, work, dispatch and the tabs.
In plain words: The Assign... button opens the assignment wizard: it lists the technicians with the skills first, then by distance to the job, with their number of open orders, and lets you assign directly or turn the order into an offer.
The assignment wizard.
The assignment wizard.
You want toDo this
Give the job to somebody elseChange the Technician field or use Assign...; the first technician is told the job was removed, the new one is notified.
CancelPress Cancel; the technician is told. Set to new brings it back.
See who did what and whereThe History tab lists every step with the time of the phone, the GPS position, the distance from the job and the source (app, Odoo, arrival detection).
Duplicate a recurring jobUse the standard Odoo Duplicate action; recurring contracts are not included (chapter 20).

Offers: any technician can accept a job

In plain words: When the dispatch is Open to the team or Offered to nearby technicians, the job is sent as an offer to the technicians that qualify (team, skills, and for nearby: within the radius of their last known position). They get a push notification and see it in the Offers list of the app with the distance. The first one to press Accept gets the job; the others are told it was taken, and a late answer is refused.
A job offered to three technicians appears with the badge Offered.
A job offered to three technicians appears with the badge Offered.
StepWhat happens
OfferTechnicians busy with a job are skipped unless nobody else qualifies. Up to technicians offered at most are chosen, nearest first.
ExpiryAfter an offer expires after minutes, the offer is renewed with a larger radius (if widen is on).
EscalationAfter the last round the job is not offered any more and the team leader (or the dispatchers) gets a to-do: Nobody accepted the job.
DeclineA technician can decline an offer (it disappears from their list) or an assigned job (it returns to the dispatcher).

The dispatch map and live location

In plain words: Field Service → Dispatch → Map shows technicians and orders on OpenStreetMap. Technicians are round badges with their initials and a status dot (green online, orange not seen for a while, grey offline), orders are pins colored by status with a red ring for urgent jobs. The map refreshes by itself every 30 seconds.
Select a technician to see the route of the day.
Select a technician to see the route of the day.
DoHow
FilterBy team, only open orders, show or hide orders and technicians.
Follow a technicianClick the name, press Today's route (the line is built from the location points of the last 8 hours).
Assign from the mapThe list To dispatch shows the orders waiting; click one and press Assign.
Location historyReporting → Location history lists the points (time, accuracy, speed, battery, network).
The raw location points.
The raw location points.
In plain words: What the app sends: latitude, longitude, accuracy, speed, heading, altitude, battery level, charging, network type and the time of the phone. Points are stored on the phone when there is no network and sent in batches (up to 500) when it returns; duplicates are ignored. The server also uses each point to detect the arrival.
Tip: Map tiles come from the public OpenStreetMap servers, which have a fair-use policy. For many dispatchers, enter the URL of your own or a paid tile provider in Settings → Dispatch map.

What the technician does

In plain words: The app is built around the job under way. On the Today list the technician sees the jobs, the next one first, with the customer, address, time, service and distance.
Today's jobs.
Today's jobs.
Jobs offered, with the distance.
Jobs offered, with the distance.
StepIn the appIn Odoo
AcceptAccept or decline an offer.The order is assigned to the technician; the other technicians are told.
On my wayOne tap, with the navigation button (opens the maps app).State On the way; position and time are recorded; tracking starts; optional email to the customer.
ArrivedA prompt appears when the phone is inside the radius, or the technician taps Arrived.State Arrived, with the distance from the customer address.
Start workStarts the timer.A work interval starts.
Hold / resumeChoose the reason (waiting for parts...), add a note.The timer pauses; the pause is recorded with its reason.
PartsSearch or scan the barcode, set the quantity.Lines on the order; the stock is moved on completion.
PhotosBefore and after photos from the camera or gallery.Photos on the order, compressed on the phone.
Checklist and notesTick the items, write what was done.Saved on the order.
SignatureThe customer signs on the screen.Image, name, time and position.
CompleteChecks that everything required is there.Timesheet, stock transfer, optional invoice and report email.
The job: customer, address, instructions, checklist.
The job: customer, address, instructions, checklist.
The active job: timer, one-tap status buttons, parts, photos.
The active job: timer, one-tap status buttons, parts, photos.

Parts, barcode, photos and signature

In plain words: The parts come from the van stock: the Inventory location of the technician. In the app, Add part opens a search by name, code or barcode, or the scanner (barcodes and QR codes). The catalog and the van quantities are stored on the phone, so searching and scanning work offline.
Parts used with their prices.
Parts used with their prices.
Scan a barcode to add a part.
Scan a barcode to add a part.
RuleDetail
StockOn completion a transfer Field service consumption from the van to the customer location is created and validated (or left to validate, see the settings). Late additions after completion are moved at once.
Out of stockBy default a technician may add a part the van does not have (the stock goes negative); turn it off in the settings for strict control.
BillableEach line has Billable; a part that is not billable is still taken out of the stock.
Locked linesOnce the stock moved, the line cannot change or be deleted; add another line to correct.
Before and after photos.
Before and after photos.
The customer signs on the phone.
The customer signs on the phone.
The photos on the order in Odoo.
The photos on the order in Odoo.
The signature, the notes and the proof rules.
The signature, the notes and the proof rules.

Time, timesheets and invoices

In plain words: The timer runs while the order is In progress. A pause stops it unless its reason says otherwise (for example Waiting on site (paid time)). The Time tab lists every interval.
Work and pause intervals of an order.
Work and pause intervals of an order.
In plain words: The invoice is a normal customer invoice (account.move) created from the order, as a draft. What it contains depends on the billing mode:
ModeLabor lineOther lines
Time and materialsWorked time (minus the minutes covered by the callout fee), rounded up to the block (15 min) and not less than the minimum (60 min), at the hourly rate.Billable parts; callout fee; travel beyond the free kilometres.
Fixed priceOne line with the price of the order or service type; time beyond the included minutes is added as extra time at the hourly rate.As above.
Materials onlyNone.Billable parts (and fees if set).
In plain words: The hourly rate is the first that exists: the rate of the service type, the rate of the technician (if the setting is on), the price of the labor product. Example: 79 minutes of work, blocks of 15, minimum 60, rate 85 → 90 minutes → 127.50; two filters at 18 → 36; callout 45 → 208.50 before tax.
The Billing tab with the estimate and the invoice.
The Billing tab with the estimate and the invoice.
  1. In Odoo press Create invoice on a completed order (or find it in Billing → To invoice), check the draft and confirm it as usual.
  2. Send invoice confirms it if needed and emails it to the invoice contact of the customer with the PDF; you can also do it from the app.
  3. Service report prints the PDF with the checklist, parts, photos and signature; it is emailed to the customer automatically if the setting is on.
Completed orders waiting to be invoiced.
Completed orders waiting to be invoiced.
Create, confirm and send the invoice from the phone.
Create, confirm and send the invoice from the phone.
Important: The email goes through the outgoing mail server of Odoo. If it is not configured, or the server refuses the message, Odoo shows the error and does not mark the invoice as sent.

The mobile app in short

In plain words: The app is written in Flutter: one code base for Android and iOS, in English and Arabic (right to left). It keeps working without a network.
AreaWhat it does
Sign inServer address, Odoo login and password. The token is kept in the secure storage of the phone.
JobsToday and upcoming jobs, offers, completed jobs; details, navigation, call the customer.
Active jobTimer, status buttons, hold reasons, parts, scanner, photos, signature, notes, checklist, invoice.
MapThe jobs and the position of the technician on OpenStreetMap.
TrackingBackground location, buffered offline, with battery friendly sampling; the privacy text and the permission steps.
SyncOutbox of actions, retries, conflict messages and a screen of problems to resolve.
SettingsLanguage, appearance, sync now, sync issues, tracking diagnostics, clear local data, sign out (and, in debug builds only, an offline simulation switch).
Jobs on the map.
Jobs on the map.
Location tracking and the privacy text.
Location tracking and the privacy text.
Settings.
Settings.
In plain words: Offline first. Everything the technician does is written to the local database and to an outbox; the screens read only the local database, so the app is as fast and usable offline as online. When a network is available, the app sends the outbox in order, each action with a unique ID (a retry can never apply it twice), then downloads what changed. The rules: the server decides assignment and cancellation; the phone decides what happened in the field (times, parts, photos, signature, notes, checklist); a pending action of the phone is never overwritten by older server data.
Working offline: actions wait in the outbox.
Working offline: actions wait in the outbox.
Actions that the server refused or that conflict are listed with the reason.
Actions that the server refused or that conflict are listed with the reason.
SituationResult
The dispatcher cancelled the job while the technician was offlineThe actions come back as conflict: order closed and are listed in the sync issues; the job shows Cancelled.
Two technicians accept the same offerThe first request wins; the other gets already taken.
A technician starts a job that was reassignedNot assigned: refused and listed.
The phone clock is wrongThe time of the phone is kept, but never earlier than the previous step of the same order.
No stock in the van (strict mode)The part is refused with insufficient stock.

Build and publish the app

In plain words: Skip this chapter if you only want to test: flutter run works on a simulator or a connected phone.
  1. Install Flutter (3.41 or newer), Android Studio, and on a Mac Xcode with CocoaPods; run flutter doctor and fix what it reports.
  2. Unzip flutter-app-source.zip in a folder without spaces.
  3. Run the setup script with your Odoo address and your own package name: dart run tools/setup.dart --url https://odoo.example.com --package com.yourcompany.fieldservice. It writes the address and the identifiers into the project; add --name "Your Company Service", --color "#0f766e" and --icon your-icon-1024.png to set the app name, the brand color and the icon (the script is safe to run again).
  4. Run flutter pub get, then flutter run to try it, signing in with a technician of your Odoo.
cd flutter-app
dart run tools/setup.dart --url https://odoo.example.com --package com.yourcompany.fieldservice
flutter pub get
flutter run --dart-define=SITE_URL=https://odoo.example.com
TargetCommandThen
Android (Google Play)flutter build appbundle --releaseUpload the .aab in the Play Console. Create the signing key once and keep it safe.
Android (internal, no store)flutter build apk --releaseSend the .apk to your technicians (allow installation from this source).
iPhone (App Store, TestFlight)flutter build ipa --releaseUpload with Xcode or Transporter; create the App ID with the capabilities Push Notifications and Background Modes (location updates).
Important: Both stores ask to justify the background location: use the sentence The app records the position of the technician during working hours and while a job is under way to dispatch jobs, navigate and prove arrival, and publish a privacy policy. The app shows its own explanation before it asks the permission.
In plain words: Push notifications (Firebase): 1) create a Firebase project; 2) add an Android app and an iOS app with your package names; 3) in Project settings → Cloud Messaging upload your APNs key for iOS; 4) in Odoo Settings → Notifications enter the project ID, the API key and the app IDs, and paste the content of a service account JSON (Project settings → Service accounts → Generate new private key). The app reads the identifiers from your server when it signs in, so the source code contains no key.

Day to day for the dispatcher

TaskWhere
Morning checkDispatch → To dispatch (new orders) and the map (who is online).
OverdueFilter Late in the orders (not started after the scheduled time).
Offers nobody tookFilter Offered, nobody took it, or the to-do in your Activities.
Complete or fix an orderOpen it; managers can Complete without proof when a signature could not be collected.
InvoicesBilling → To invoice, then Invoices.
Parts consumedBilling → Parts used lists the transfers from the vans.
Message a technicianTechnicians → Send a notification sends a push message to chosen technicians.
AnalysisReporting → Analysis: orders and worked hours by service, technician and status.
Analysis of the orders.
Analysis of the orders.
The list of orders with the filters Late, To invoice, Offered...
The list of orders with the filters Late, To invoice, Offered...

Security and privacy

TopicHow it is handled
AccessThe app signs in with the Odoo login; internal users with the group Technician only. Record rules: a technician sees only their own orders and the orders offered to them. Accounts with two-factor authentication cannot sign in to the app.
TokensA random token per device, only its hash is stored in Odoo, devices unused for 180 days are forgotten. Devices lists them; a technician can be signed out everywhere. Odoo's own protection slows down repeated wrong passwords (a cooldown after five failures).
Orders are protectedEvery action of the app is checked on the server: the order must be assigned to the user, the state machine must allow the move, and the proof rules apply.
History cannot be changedThe events (state, time, GPS) cannot be edited or deleted, not even by a manager.
LocationCollected only while the setting says so, with a privacy text and the system permission; points older than the retention (30 days by default) are deleted every day. Customers do not see the technician's position.
SecretsThe Firebase service account is readable only by Odoo administrators. The app contains only public identifiers.
Tip: Tell your technicians what is collected and when. In some countries employee location tracking requires a written notice or consent: use the privacy text of the settings and your own policy.

Good to know

LimitDetail
Recurring maintenance contractsNot included. Duplicate orders or use Odoo scheduled actions.
Route optimisationNot included. The map and the assignment wizard help to choose by distance; navigation opens the maps app of the phone.
Lot and serial numbersThe app adds parts by quantity; serial numbers can be noted in the checklist or the notes.
Customer portalNot included. The customer receives emails (on the way, service report, invoice).
Background location on phonesAndroid and iOS may stop apps to save the battery. Ask technicians to allow always location and disable battery optimisation for the app; the buffer keeps the points until the phone reconnects.
Odoo versionBuilt and tested on Odoo 19.0. Other versions need an adaptation of the views and some methods.
MapsPublic OpenStreetMap tiles are for moderate use; configure another tile server for heavy use.

For developers

In plain words: Skip this chapter if you only use the product. The complete contract of the app API is in documentation/API.md.
# is the server reachable?
curl https://odoo.example.com/api/fsm/v1/ping
# {"ok": true, "api_version": 1, "server_time": "2026-10-26T08:00:00Z"}

# sign in (returns a token and the configuration)
curl -X POST https://odoo.example.com/api/fsm/v1/auth/login -H 'Content-Type: application/json' \
  -d '{"login": "sara@example.com", "password": "...", "device": {"id": "abc", "platform": "android"}}'

# send buffered location points
curl -X POST https://odoo.example.com/api/fsm/v1/tracking/batch -H "Authorization: Bearer $TOKEN" -H 'Content-Type: application/json' \
  -d '{"points": [{"uuid": "1", "lat": 25.2, "lng": 55.27, "speed": 8.3, "heading": 90, "battery": 80, "network": "cellular", "recorded_at": "2026-10-26T08:00:00Z"}]}'

# push the queued actions and pull the changes
curl -X POST https://odoo.example.com/api/fsm/v1/sync -H "Authorization: Bearer $TOKEN" -H 'Content-Type: application/json' \
  -d '{"cursor": null, "ops": [{"uuid": "9d1c...", "type": "transition", "order_id": 12, "device_time": "2026-10-26T08:01:00Z", "payload": {"to": "en_route", "lat": 25.2, "lng": 55.27}}]}'
AreaEndpoints under /api/fsm/v1
SessionGET /ping, /config, /auth/me; POST /auth/login, /auth/logout, /auth/push-token
SyncPOST /sync (operations: transition, claim, decline, material_set, photo_add, signature_set, notes_set, checklist_set, order_create, invoice)
TrackingPOST /tracking/batch (also /api/fsm/tracking/batch)
DataGET /jobs/available, /orders/<id>, /catalog/products, /catalog/lookup?barcode=, /van-stock, /customers
FilesGET /photos/<id>, /orders/<id>/signature, /orders/<id>/invoice.pdf, /orders/<id>/report.pdf
In plain words: Calls send Authorization: Bearer <token> and optionally Accept-Language. Every operation of /sync has a unique uuid and is answered applied, duplicate, rejected or conflict with a code. The module has 130+ automated tests (--test-tags /taqnix_fsm) and the app has unit tests (flutter test).

Troubleshooting

ProblemWhat to do
The app cannot connectOpen https://your-odoo/api/fsm/v1/ping on the phone: it must answer {"ok": true}. Check https, the certificate, the address without a trailing slash and that the module is installed on that database (the right one if you have several: add --db-filter or the dbfilter setting).
Sign-in says the account is not a technicianAdd the user in Technicians (it gets the group automatically).
The technician sees no jobsThe order must be Assigned to that user (not New). Open the order and press Dispatch.
No offers appearCheck the team and the skills, the radius and that the technician has a recent location (tracking on) for nearby offers.
The map is empty or whiteThe browser must reach the tile server; set the tile URL in the settings.
No timesheetThe technician needs an employee and the project of the settings; see the to-do created for the dispatcher.
Parts are not movedCheck the setting When parts are used and that the products are storable; look at Billing → Parts used.
The invoice is not emailedSet up the outgoing mail server in Odoo and check the customer email.
No push notificationsCheck the Firebase identifiers and the service account in the settings, the APNs key for iPhone, and that the technician allowed notifications. Technicians → Send a notification tells you when nobody could be reached.
Location stops in the backgroundAllow location always and remove battery optimisation for the app on the phone.

Support

Installation help and bug fixes are included for 6 months, with lifetime updates. Contact us through the marketplace page where you bought the module or write to support@taqnix.com with your Odoo version and a screenshot.