CRM migration

Migrate from Dynamics 365 Field Service to Odoo CRM

Field-level mapping, validation, and rollback between Dynamics 365 Field Service and Odoo CRM. We move data and schema; workflows are rebuilt natively in Odoo CRM.

Dynamics 365 Field Service logo

Dynamics 365 Field Service

Source

Odoo CRM

Destination

Odoo CRM logo

Compatibility

75%

9 of 12

objects map 1:1 between Dynamics 365 Field Service and Odoo CRM.

Complexity

BStandard

Timeline

48–72 hours

Rollback included Accuracy guarantee Field-level validation

Overview

What this migration involves

Microsoft Dynamics 365 Field Service organizes service operations around Work Orders, Bookable Resources, Incidents, and Work Order Products — a schema designed for dispatch, scheduling, and field-technician management. Odoo CRM uses a simpler model: crm.lead for opportunities, res.partner for contacts and companies, and sale.order for quotes and contracts. The migration must collapse D365's field-service object graph into Odoo's standard CRM objects while preserving the operational context that drives your service business. We map Work Orders to a combination of crm.lead records (for customer-facing opportunities) and project.task records (for internal work tracking), Bookable Resources to res.partner with a custom technician type, and Work Order Incidents to crm.lead.tag or custom fields on the opportunity. Owner resolution happens via email match against Odoo users. Activities — service calls, completed jobs, notes — migrate as mail.message and crm.lead.calendar.event records with original timestamps preserved. Custom fields on Work Orders and Bookable Resources become custom fields on crm.lead and res.partner using Odoo's x_studio or custom field conventions. Workflows, booking rules, Resource Scheduling Optimization policies, and Service Agreements do not migrate — they require manual rebuild in Odoo's Automation menu. The migration uses Odoo's XML-RPC API with batched writes to avoid throttling, and FlitStack runs a sample migration with field-level diff before the full cutover.

Field-level fidelity

Every standard and custom field arrives verified.

Schema-aware mapping

AI proposes the map; you confirm before any record moves.

Relationships preserved

Parent–child, lookups, and ownership stay linked.

Full activity history

Calls, emails, meetings — with original timestamps.

Attachments & notes

Documents, uploads, and inline notes move with the record.

Why teams make this switch

Two sides of the same decision

Leaving

Dynamics 365 Field Service logo

Dynamics 365 Field Service

What's pushing teams away

  • Implementation requires certified Microsoft partners for anything beyond basic configuration; simple customizations that competitors handle in-house demand developer resources, inflating total cost of ownership.
  • Per-user licensing at $105/month compounds quickly—technicians, dispatchers, supervisors, and parts staff each require seats, and the true headcount often exceeds initial estimates.
  • Performance degrades when Work Order histories grow large; pages load slowly and offline sync timeouts occur in datasets exceeding tens of thousands of records without careful FetchXML tuning.
  • Change management and staff training are underestimated; technicians accustomed to simple mobile tools struggle with the learning curve, leading to low adoption and shadow systems.
  • The platform integrates poorly with non-Microsoft ERPs out of the box; customers using Business Central face custom integration work, and those on other ERP systems must build middleware.

Choosing

Odoo CRM logo

Odoo CRM

What's pulling them in

  • Teams choose Odoo CRM for its modular architecture — one base install with one-click app additions means they can adopt CRM alone and add accounting, inventory, or sales later as the business grows.
  • Small businesses pick Odoo because the Community edition is free and open-source, with no per-user or contact limits, allowing full evaluation before committing to a paid Enterprise tier.
  • The drag-and-drop Kanban pipeline and AI lead scoring are highlighted across G2 reviews as concrete features that make lead management faster and more visual than spreadsheet-based workflows.
  • Odoo's native integration with email, live chat, SMS, VoIP, and WhatsApp means inbound leads from multiple channels feed into a single pipeline without third-party middleware.
  • Companies in retail, supply chain, and construction value that Odoo's CRM module shares the same PostgreSQL database and UI as its ERP modules, eliminating data silos between sales and operations.

Object mapping

How Dynamics 365 Field Service objects map to Odoo CRM

Each row shows how a Dynamics 365 Field Service object lands in Odoo CRM, including any object-level transformations, lookup resolution, or schema-design dependencies.

Typical mapping — final map is confirmed during the sample migration step.

Dynamics 365 Field Service

Account (msdyn_account / account)

maps to

Odoo CRM

res.partner

1:1
Fully supported

D365 Account maps to Odoo res.partner where is_company=True. Primary address, phone, website, and industry fields map directly using Odoo's standard address fields. Parent-account hierarchies in D365 map to res.partner.parent_id in Odoo. If the account is a billing entity only, it migrates as a company-type partner; Odoo does not distinguish between 'billing' and 'service' accounts natively.

Dynamics 365 Field Service

Contact (contact)

maps to

Odoo CRM

res.partner

1:1
Fully supported

D365 Contact maps to Odoo res.partner where is_company=False. Name, email, phone, mobile, job title, and address fields migrate directly. D365's multiple-contact-per-account model is natively supported by Odoo's res.partner structure — no junction table required. Owner (user_id) resolves via email match against Odoo users.

Dynamics 365 Field Service

Bookable Resource (bookableresource)

maps to

Odoo CRM

res.partner + project.resource

many:1
Fully supported

D365 Bookable Resource has no direct Odoo equivalent. FlitStack creates a res.partner record with a custom 'Technician' partner category for each resource, preserving resource name, email, and organizational unit. If your D365 setup uses resource characteristics (skills, certifications), those migrate as crm.lead.tag entries applied to work-order-linked opportunities — Odoo's project.resource model is used only if Odoo Project is deployed alongside CRM.

Dynamics 365 Field Service

Work Order (msdyn_workorder)

maps to

Odoo CRM

crm.lead + project.task

1:many
Fully supported

D365 Work Order is the central service record and cannot map to a single Odoo object. The customer-facing context (account, contact, address, service type) maps to crm.lead as an opportunity with the work order name as the opportunity name. The internal work-tracking context (assigned technician, scheduled date, incident summary) maps to project.task if Odoo Project is in scope; otherwise it stores as custom fields on the crm.lead. The split is determined by whether your Odoo deployment includes the Project app.

Dynamics 365 Field Service

Work Order Incident (msdyn_workorderincident)

maps to

Odoo CRM

crm.lead.tag + custom fields

many:1
Fully supported

D365 Work Order Incidents record problems or symptoms per work order. Multiple incidents per work order are merged into a set of crm.lead.tag entries on the corresponding Odoo opportunity (e.g., 'Incident: Electrical Fault', 'Incident: Motor Failure'). If incident codes carry pricing or billing weight, those values migrate as custom decimal fields on the opportunity rather than as tags. Symptom codes and incident types without a meaningful Odoo tag equivalent are preserved in an 'Incident_History__c' custom field as a text block.

Dynamics 365 Field Service

Work Order Product (msdyn_workorderproduct)

maps to

Odoo CRM

sale.order.line

1:1
Fully supported

D365 Work Order Products (parts and materials applied to a work order) map to Odoo sale.order.line records on the linked quotation or sale order. Product name, quantity, unit cost, and unit price migrate directly. If the work order has no linked quote, FlitStack creates a draft sale.order attached to the opportunity's partner. The product.product record must exist in Odoo before the line can map — FlitStack validates product SKU existence and flags missing products before migration.

Dynamics 365 Field Service

Work Order Service (msdyn_workorderservice)

maps to

Odoo CRM

sale.order.line

1:1
Fully supported

D365 Work Order Services (labor line items) map to sale.order.line with the service flag set to True. Duration and hourly rate from D365 migrate as quantity and unit price on the Odoo line. If D365 tracks service task type (diagnostic, repair, maintenance), that value becomes a crm.lead.tag on the parent opportunity. Tax codes on service lines map to Odoo's account.tax based on the D365 tax code value — value-by-value mapping is required per jurisdiction.

Dynamics 365 Field Service

Case / Service Task (incident)

maps to

Odoo CRM

crm.lead

1:1
Fully supported

D365 Cases (service incidents not tied to a work order) map to crm.lead records with a dedicated 'Case' stage in the Odoo pipeline. Subject, description, priority, and status migrate as crm.lead name, description, priority, and stage. If cases have a parent-account or parent-contact, those link via the standard partner_id lookup in Odoo. Case resolution notes and internal comments migrate as mail.message records attached to the lead.

Dynamics 365 Field Service

Agreement / Service Contract (msdyn_agreement)

maps to

Odoo CRM

sale.subscription

1:1
Fully supported

D365 Agreements (recurring service contracts) map to Odoo sale.subscription records. Contract name, start/end dates, billing frequency, and recurring amount migrate directly. If the agreement contains a line-item schedule (services covered), those lines migrate as sale.subscription.line records. One-time setup fees on the agreement map as a non-recurring line on the subscription. Billing term (advance/arear) maps to Odoo's invoicing policy on the subscription product.

Dynamics 365 Field Service

Customer Asset (msdyn_customerasset)

maps to

Odoo CRM

stock.production.lot + custom field

1:1
Fully supported

D365 Customer Asset links equipment to a customer account with serial number, product, and installed date. Odoo has no native customer asset entity — FlitStack creates stock.production.lot records for each asset serial number and attaches a custom 'Customer_Account__c' field linking the lot to the customer partner. Asset lifecycle status (Active, Inactive, Under Repair) migrates as a custom selection field on the lot. If your Odoo deployment includes the Maintenance app, assets can alternatively map to maintenance.equipment with the customer as the partner_id.

Dynamics 365 Field Service

Resource Booking / Schedule (bookableresourcebooking)

maps to

Odoo CRM

project.task + calendar.event

1:1
Fully supported

D365 Resource Bookings assign technicians to work orders with start/end times. Each booking maps to a project.task record with the assigned technician as the user_id and the booking window as task planned date range. If the booking has a meeting context (customer on-site visit), a calendar.event is also created in Odoo with the customer partner linked. Odoo's standard calendar uses mail.activity.type records for activity types — FlitStack maps D365 booking type codes to the closest Odoo activity type by name match.

Dynamics 365 Field Service

Product / Service Item (product)

maps to

Odoo CRM

product.product + product.template

1:1
Fully supported

D365 Field Service products (parts) and service items map to Odoo product.product records. Product name, SKU, list price, standard cost, and product type (inventory vs. consumable vs. service) migrate directly. Product categories from D365 map to product.category in Odoo. If D365 uses product variants (size, color), those migrate as Odoo product variants on the same template.

Gotchas + challenges

What specifically takes care here

Platform-specific issues from each side, plus the pair-specific challenges that don't show up on either platform's page on its own.

Dynamics 365 Field Service logo

Dynamics 365 Field Service gotchas

High

Dataverse service protection API limits throttle bulk exports

Medium

Offline profile FetchXML tuning is source-environment-specific

Medium

Project Operations integration has bidirectional sync limitations

Medium

Copilot add-on credits do not migrate and reset at zero

Low

File attachments stored in SharePoint require separate file migration

Odoo CRM logo

Odoo CRM gotchas

High

Odoo.sh version gating blocks assisted migrations from trial

High

Enterprise modules fail to install on Community after database restore

Medium

Custom module view inheritance breaks between Odoo major versions

Medium

Custom fields risk losing their application context on Community

Low

API access for Community is gated behind the Custom Plan

Pair-specific challenges

  • Work Order to opportunity split requires post-migration manual tagging

    D365 Work Orders carry both customer-facing context (account, contact, service type) and internal operational context (technician assignment, incident codes, parts used). Odoo CRM has no single object that holds both. FlitStack splits each Work Order into a crm.lead for the customer-facing opportunity and project.task for the job-tracking context. The split means your sales team sees the opportunity in the CRM pipeline, but the operational dispatch detail (which technician, which booking window) lives in project.task — visible only if you deploy Odoo Project alongside CRM. This architectural split is unavoidable; Odoo does not have a native Field Service module in its standard CRM app.

  • Bookable Resource has no native Odoo equivalent and requires partner-category tagging

    D365 Bookable Resource is a first-class entity in the Field Service data model — it represents technicians, crews, and equipment with separate scheduling, characteristics, and pay-rate schemas. Odoo CRM has no resource scheduling entity. FlitStack maps Bookable Resources to res.partner records tagged with a custom 'Technician' category, but D365-specific attributes like resource characteristics (skills, certifications), resource type (user vs. contact vs. equipment), and Organizational Unit hierarchy cannot map directly. These require a post-migration review where your Odoo admin defines how to represent those attributes using Odoo's custom field system or the project.resource model if Odoo Project is in scope.

  • D365 tax codes on work order products need value-by-value mapping to Odoo account.tax

    D365 Field Service carries tax codes on Work Order Products and Services (msdyn_workorderproduct, msdyn_workorderservice) that vary by jurisdiction and product type. Odoo's account.tax model requires a separate tax record per rate and per fiscal position. There is no automatic translation between D365 tax codes and Odoo tax IDs — FlitStack creates a value-mapping table during the planning phase, mapping each D365 tax code label to an existing or newly-created account.tax record in Odoo. If your D365 setup uses complex tax combinations (e.g., different rates for parts vs. labor in the same jurisdiction), the mapping table must capture all of them before migration begins.

  • Customer Asset has no native Odoo counterpart and maps to stock.production.lot with custom linkage

    D365 Customer Asset (msdyn_customerasset) links equipment to a customer account with serial number, product, installed date, and operational status. Odoo CRM has no customer asset entity — the closest native object is stock.production.lot for serial-number tracking, which lives in the inventory module, not CRM. FlitStack creates stock.production.lot records for each customer asset and attaches a custom partner-linking field. However, the asset-to-work-order linkage that D365 enforces natively does not exist in Odoo CRM by default. Work orders linked to assets in D365 will lose that automated relationship in Odoo unless your team builds a custom module or uses Odoo's maintenance.app to manage equipment-to-task associations.

  • Resource Scheduling Optimization policies do not migrate and require Odoo-side rebuild

    D365 Field Service's Resource Scheduling Optimization (RSO) rules — including territory definitions, constraint sets, scheduling parameters, and booking setup rules — are configuration objects that live outside the data API. Odoo CRM has no native RSO equivalent; scheduling in Odoo relies on the calendar module, project task planning, or third-party OCA modules. FlitStack migrates the resource booking records (which technician was booked when) but cannot export the optimization policies that created those bookings. Your Odoo admin must rebuild scheduling constraints and territory rules in whatever scheduling tool you deploy alongside Odoo CRM.

Migration approach

Six steps for a successful Dynamics 365 Field Service to Odoo CRM data migration

  1. Assess D365 Field Service schema and Odoo CRM target configuration

    FlitStack AI begins by querying your D365 Field Service instance via the Dataverse API to inventory all Work Order entities, Bookable Resource definitions, Work Order Incident types, and Agreement records. We simultaneously inspect your Odoo CRM target instance to identify existing crm.lead stages, res.partner categories, product.product records, and sale.subscription configuration. The gap analysis produces a migration map: which D365 objects map to which Odoo models, which fields are direct, which require custom field creation, and which D365 data cannot map to a native Odoo object. This schema map is reviewed with your team before any data moves.

  2. Validate owner and user resolution across both platforms

    D365 Bookable Resources and Work Order owners carry a user reference (Azure AD object ID in D365). FlitStack resolves these by email address against Odoo res.users records. Resources without a matching Odoo user are flagged in a pre-migration report — your team either creates Odoo user accounts for those technicians before migration or designates a fallback dispatcher who inherits their records. Accounts and Contacts are resolved similarly: D365 Account and Contact owner IDs map to Odoo user_id on res.partner. This step prevents orphan records at migration time.

  3. Migrate foundational entities first: Accounts, Contacts, Products

    FlitStack sequences the migration to honor foreign-key dependencies. res.partner records (Accounts and Contacts) migrate first so that Work Order and Case records can resolve their customer links. product.product records migrate next so that Work Order Product and Service lines can reference existing Odoo products. Custom fields required for the migration — such as Original_Create_Date__c on res.partner, Source_System_ID__c on crm.lead, and Technician_Category__c for Bookable Resources — are created in Odoo during this phase via XML-RPC field creation calls.

  4. Migrate Work Orders and Cases to crm.lead with field-level diff validation

    With foundations in place, FlitStack migrates Work Orders to crm.lead records and Work Order Incidents to crm.lead.tag entries. Each opportunity inherits the D365 Work Order name, account, primary incident type, total amount, and status as stage. Cases (D365 incidents not tied to a work order) migrate as separate crm.lead records with a dedicated 'Case' stage. A sample migration of 100–300 records runs first; FlitStack generates a field-level diff comparing source D365 values against destination Odoo values. Your team reviews the diff to confirm incident type mapping, stage routing, and owner assignment before the full migration commits.

  5. Migrate Work Order Products, Services, and Resource Bookings with delta window

    Work Order Product and Service lines migrate as sale.order.line records attached to the opportunities created in the previous step. Resource Bookings migrate as project.task records linked to the technician res.partner records created from Bookable Resources. During the full migration, a delta-pickup window (24–48 hours) captures any D365 Work Orders created or modified during the cutover window. FlitStack's audit log records every insert operation; one-click rollback reverts all migrated records if reconciliation against the D365 source fails. The migration uses batched XML-RPC writes to stay within Odoo's API rate limits.

Platform deep dives

Context on both ends of the pair

Dynamics 365 Field Service logo

Dynamics 365 Field Service

Source

Strengths

  • Intelligent schedule board with multi-constraint optimization (skills, location, SLA, travel time) reduces manual dispatch effort on large technician fleets.
  • IoT integration via Connected Field Service enables proactive maintenance alerts that auto-create Work Orders before equipment fails.
  • Native mobile app with robust offline mode allows technicians to work disconnected and sync changes when connectivity returns.
  • Deep Dataverse foundation means seamless data sharing with Microsoft Dynamics 365 Sales , Customer Service, and Power Platform apps without middleware.
  • Microsoft's regular release cadence keeps the platform current with AI features, Copilot assistance, and updated compliance certifications.

Weaknesses

  • Per-user licensing at $105/month creates predictable cost inflation as technician headcount grows, with no meaningful volume discounts for large fleets.
  • Implementation and ongoing customization require certified Microsoft partners or developer-staffed IT teams, limiting agility for mid-market organizations.
  • Performance degrades in large datasets without careful FetchXML optimization; offline sync timeouts are common without proactive query tuning.
  • Integration with non-Microsoft ERP systems (SAP, Oracle, NetSuite) requires custom middleware or third-party connectors that add cost and maintenance overhead.
  • Schema changes between release waves can break custom field references, requiring re-validation of data mappings after each major update.
Odoo CRM logo

Odoo CRM

Destination

Strengths

  • Modular open-source architecture lets teams start with CRM and add ERP apps as needs grow, all sharing one PostgreSQL database.
  • Free Community edition with no contact limits and full source code access means zero licensing cost for evaluation and small deployments.
  • Drag-and-drop Kanban pipeline with AI lead scoring gives a visual, prioritized view of the sales funnel without requiring custom configuration.
  • Native integrations with email, live chat, SMS, VoIP, WhatsApp, and social media feed all inbound leads into a single unified inbox.
  • Active Odoo Community Association (OCA) maintains dozens of community-maintained modules on GitHub for extended functionality.

Weaknesses

  • Gmail and email integration reliability is a recurring complaint — threads drop and conversations scatter across inboxes, disrupting sales team workflows.
  • Enterprise edition pricing stacks quickly: multiple apps at per-user rates ($25–$50/user/month) plus Odoo.sh hosting costs more than many SMBs anticipate.
  • Setup and configuration complexity increases significantly once custom fields, automation rules, and multiple installed modules are in play.
  • Odoo.sh trial databases run on a version (e.g., 18.3) that is not directly migratable to Odoo.sh, blocking the assisted migration path Odoo advertises.
  • Version upgrades between major Odoo releases (e.g., 17→18) frequently break custom module view definitions and XPath expressions, requiring manual remediation.

Complexity grading

How hard is this migration?

Standard CRM migration. All 8 core objects map 1:1 between Dynamics 365 Field Service and Odoo CRM.

B

Overall complexity

Standard migration

Derived from compatibility, mapping clarity, API constraints, and data volume across Dynamics 365 Field Service and Odoo CRM.

  • Object compatibility

    A

    All 8 core objects map 1:1 between Dynamics 365 Field Service and Odoo CRM.

  • Field mapping clarity

    C

    Field mapping is derived from defaults — final spec confirmed during the sample migration.

  • Timeline complexity

    B

    8-object category — typical timelines run 2–7 days end-to-end.

  • API constraints

    B

    Dynamics 365 Field Service: Service protection limits enforced per org; specific numeric thresholds are not publicly documented by Microsoft and vary by workload type.

  • Data volume sensitivity

    A

    Dynamics 365 Field Service exposes a bulk API — large-volume migrations stream efficiently.

Estimator

Estimate your Dynamics 365 Field Service to Odoo CRM migration cost

Rule-based pricing — no per-record fees, no manual quotes. Migrations over 2M records are scoped individually.

Step 1

What are you migrating?

Pick a category, then your source and destination platforms.

Category

FAQ

Frequently asked questions about Dynamics 365 Field Service to Odoo CRM data migrations

Answers to the questions buyers ask most during Dynamics 365 Field Service to Odoo CRM migration scoping. Not seeing yours? Book a call.

Can't find your answer?

Walk through your Dynamics 365 Field Service to Odoo CRM migration with a real engineer — 30 minutes, free, written quote within 24 hours.

Book a free 30 minute consultation

Most D365 Field Service to Odoo CRM migrations complete in 48–72 hours of clock time for under 25,000 records spanning Accounts, Contacts, Work Orders, and Bookable Resources. Larger setups with more than 250,000 records or complex Work Order incident hierarchies — where each work order carries multiple incident lines requiring tag or custom-field processing — extend to 5–10 days. The longest planning step is building the incident-to-tag value-mapping table and validating that D365 tax codes have corresponding account.tax records in Odoo before migration begins.

Adjacent paths

Related migrations to explore

Ready when you are

Move from Dynamics 365 Field Service.
Land in Odoo CRM, intact.

Tell us record counts and timeline. We'll come back with a written quote inside 1 business day — no commitment, no sales pitch.

Accuracy guarantee Rollback included Quote in 1 business day