CRM migration
Field-level mapping, validation, and rollback between Microsoft Dynamics 365 Sales and Odoo CRM. We move data and schema; workflows are rebuilt natively in Odoo CRM.
Microsoft Dynamics 365 Sales
Source
Odoo CRM
Destination
Compatibility
11 of 14
objects map 1:1 between Microsoft Dynamics 365 Sales and Odoo CRM.
Complexity
BStandard
Timeline
6-10 weeks
Try the reverse
Overview
Moving from Microsoft Dynamics 365 Sales to Odoo CRM means leaving the Microsoft Dataverse ecosystem for an open-source, PostgreSQL-backed platform with a fundamentally different CRM object model. Dynamics 365 separates Leads from Opportunities with an explicit qualification pipeline; Odoo CRM uses a unified Opportunities object with a Stage field that covers both unqualified and qualified deals. We resolve that structural difference during scoping, map Accounts to Companies, preserve opportunity probability and close-date history, and use the Dataverse bulk export API with batch chunking for large datasets. Custom fields require pre-creation in Odoo's Studio interface before our import job writes data. Power Automate workflows, Dataverse plug-ins, and Dynamics reports do not migrate; we deliver a written inventory of every active automation and report that the customer's Odoo admin rebuilds using Odoo Studio and automated actions. Odoo's per-app pricing model, starting at €25 per user per month for the CRM app, typically reduces subscription costs by 40-70 percent compared to Microsoft Dynamics 365 Sales Professional at $80 per user per month after the October 2024 increase.
Every standard and custom field arrives verified.
AI proposes the map; you confirm before any record moves.
Parent–child, lookups, and ownership stay linked.
Calls, emails, meetings — with original timestamps.
Documents, uploads, and inline notes move with the record.
Source platform
Microsoft Dynamics 365 Sales platform overview
Scorecard, SWOT, gotchas, and pricing for Microsoft Dynamics 365 Sales .
Destination platform
Odoo CRM platform overview
Scorecard, SWOT, gotchas, and pricing for Odoo CRM.
Data migration guide
The complete Odoo CRM migration guide
Data model, import mechanisms, field mapping strategy, pitfalls, and cutover — by the engineers running it.
Source platform guide
Microsoft Dynamics 365 Sales migration guide
Understand the data you're exporting from Microsoft Dynamics 365 Sales before mapping it.
Destination checklist
Odoo CRM migration checklist
Pre- and post-cutover tasks for moving onto Odoo CRM.
Source checklist
Microsoft Dynamics 365 Sales migration checklist
Exit checklist for unwinding your Microsoft Dynamics 365 Sales setup cleanly.
Why teams make this switch
Leaving
What's pushing teams away
Choosing
What's pulling them in
Object mapping
Each row shows how a Microsoft Dynamics 365 Sales 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.
Microsoft Dynamics 365 Sales
Account
Odoo CRM
Company
1:1Dynamics 365 Accounts map to Odoo Companies, which serve as the organizational parent record for Contacts. We preserve Account Name, Industry, Website, Address fields, and the primary contact association. Odoo Companies do not have a native Account Number field, so we map the Dynamics Account Number to the Company's Company Registry or VAT field, or to a custom Char field depending on the customer's use of those identifiers. The Company is created before any Contact import so that the Contact's Company_id lookup resolves at insert time.
Microsoft Dynamics 365 Sales
Contact
Odoo CRM
Contact
1:1Dynamics 365 Contacts map directly to Odoo Contacts. We preserve FirstName, LastName, Email, Phone, Mobile, Job Title, and the parent Company lookup. The Dynamics ParentContact relationship (for assistant or spouse links) maps to a custom Many2one field or is flattened into a note. Contact ownership (OwnerId) maps to the Odoo Salesperson field on the contact record, which controls activity assignment and pipeline visibility under Odoo's access control model.
Microsoft Dynamics 365 Sales
Lead
Odoo CRM
Lead
1:1Dynamics 365 Leads map to Odoo CRM Leads. We preserve Lead Score, Lead Source, the qualification status fields (state, status reason), and all custom lead fields. The Dynamics Lead-to-Opportunity conversion produces a new Opportunity record; we map both the pre-conversion Lead and the resulting Opportunity separately so that the full qualification history is preserved even after the customer transitions the opportunity through the pipeline.
Microsoft Dynamics 365 Sales
Opportunity
Odoo CRM
Opportunity
1:1Dynamics 365 Opportunities map to Odoo CRM Opportunities (the crm.lead record type of type=opportunity). We preserve the Estimated Revenue (Expected Revenue), Close Date (Date Deadline), Probability (mapped to Odoo's probability percentage per stage), and StageName (mapped to the Odoo Stage ID within the sales team pipeline). Loss Reason and Win Reason from Dynamics custom fields become Odoo Lost Reason values or custom Char fields. The parent Account maps to the Opportunity's Partner_id (the linked Company), and the primary Contact maps to Partner_id's primary contact role.
Microsoft Dynamics 365 Sales
Pipeline and Stage
Odoo CRM
Pipeline and Stage
lossyDynamics 365 pipeline configurations (one or more pipelines with named stages and probability percentages) map to Odoo Sales Teams and Stage configurations within each team. We create an Odoo Sales Team per Dynamics pipeline, map each Dynamics stage name to a corresponding Odoo Stage with the same sequence order, and preserve the probability percentage as the Odoo Stage's probability value. Stages with no Odoo equivalent are created as custom stages before migration.
Microsoft Dynamics 365 Sales
Quote
Odoo CRM
Quotation
1:1Dynamics 365 Quotes map to Odoo Sale Orders in the Quotation state. We preserve the Quote Number, Description, line items with product references and quantities, pricing from the assigned Price List, Discount, and Tax fields. The Quote's expiration date maps to Odoo's Valid Until field. The parent Account and Opportunity lookups map to the Sale Order's Partner_id and Opportunity_id (if the Odoo CRM Opportunity is linked to the Sale Order via the sale_crm module). Revoked or expired Quotes in Dynamics are imported as Cancelled or Lost Odoo quotations.
Microsoft Dynamics 365 Sales
Order
Odoo CRM
Sale Order
1:1Microsoft Dynamics 365 Sales Orders map to Odoo Sale Orders in the Sale Order state (confirmed, not quotation). We preserve the Order Number, line items, quantities, pricing, taxes, and the parent Account and Opportunity references. The Order's state (Fulfilled, Invoiced, Cancelled) maps to the corresponding Odoo Sale Order state. If the customer uses Odoo Accounting, the Sale Order's Invoice Status is set to indicate whether an invoice has been created.
Microsoft Dynamics 365 Sales
Product
Odoo CRM
Product
1:1Dynamics 365 Products map to Odoo Products. We preserve Product Name, Product Number (mapped to Odoo's Reference or Barcode field), Unit of Measure, Product Type (Stockable, Consumable, Service), and Cost (Standard Price). Dynamics Product Type (Sales, Miscellaneous) maps to Odoo's Product Type selection. The Product's default vendor (Vendor Price on Dynamics) maps to Odoo's vendor on the Purchase tab of the Product form.
Microsoft Dynamics 365 Sales
Price List
Odoo CRM
Pricelist
1:1Dynamics 365 Price Lists map to Odoo Pricelists. Each Price List becomes an Odoo Pricelist with the same name and type (Sales Pricelist). Price List Item rows map to Odoo Pricelist Rule lines: Dynamics Unit Price becomes the Base Price on the rule, quantity-based discounts map to Odoo's Min Quantity and Price computation fields, and percentage discounts map to Odoo's Percentage (discount) field. Currency on the Dynamics Price List maps to the Odoo Pricelist's Currency setting. If the customer uses multiple currencies, we configure a product.category-based pricelist fallback in Odoo before migration.
Microsoft Dynamics 365 Sales
Activity: Task, Email, Phone Call, Appointment
Odoo CRM
Activity
1:1Dynamics 365 Activities (Tasks, Emails, Phone Calls, Appointments) map to Odoo Mail Activity records linked to the target CRM record. The activity type, subject, description, date, and duration transfer to Odoo's activity_type_id, summary, note, date_deadline, and duration fields. OwnerId from Dynamics maps to Odoo's user_id on the activity, which drives the sales rep's activity list. Activity records that reference inactive Dynamics owners are mapped to a designated migration administrator user at the destination to avoid orphaning.
Microsoft Dynamics 365 Sales
Note and Attachment
Odoo CRM
Note and Attachment
1:1Dynamics 365 Notes migrate as Odoo Mail Messages with a note subtype, attached to the parent CRM record (Company, Contact, Lead, or Opportunity). The Note body transfers as plain text or HTML. Attachments stored in SharePoint or Dataverse blob storage are downloaded during extraction and uploaded to Odoo as ir.attachment records linked to the same parent record via res_model and res_id. Attachment file names and content types are preserved.
Microsoft Dynamics 365 Sales
User and Owner
Odoo CRM
User
1:1Dynamics 365 Users who own CRM records map to Odoo Users. We match by email address as the primary key. Each Dynamics Business Unit maps to an Odoo Access Control Group (res.groups) to replicate visibility boundaries. Inactive Dynamics Users without corresponding Odoo User records are placed in a reconciliation queue; the customer's Odoo administrator provisions the missing users before the migration resumes. OwnerId references on Opportunities, Activities, and Notes are resolved against this user map before import.
Microsoft Dynamics 365 Sales
Custom Table
Odoo CRM
Custom Field or Model
lossyDynamics 365 custom tables above the Professional tier's 15-table limit require schema simplification or Enterprise licensing before migration. For environments within the limit, each Dynamics custom table maps to an Odoo custom model created via Odoo Studio before migration: the table name becomes the model name (x_<tablename>), columns become fields, and lookup relationships to standard entities (Account, Contact, Opportunity) map to Odoo Many2one fields on the custom model. We coordinate with the customer's admin to pre-create all destination custom models and fields in a staging environment before the import job runs.
Microsoft Dynamics 365 Sales
Territory
Odoo CRM
Sales Team or Tag
lossyDynamics 365 Territory management (available on Enterprise tier only) maps to Odoo Sales Teams or to Tags on CRM records. Each Dynamics Territory becomes an Odoo Sales Team with its own pipeline and member list, or alternatively, the Territory name is stored as a tag on Opportunities and Accounts. The customer selects the mapping strategy during scoping based on whether they plan to use Odoo's multi-team reporting features. Territory hierarchies flatten to a single level in the destination, as Odoo Sales Teams do not support nested hierarchies natively.
| Microsoft Dynamics 365 Sales | Odoo CRM | Compatibility | |
|---|---|---|---|
| Account | Company1:1 | Fully supported | |
| Contact | Contact1:1 | Fully supported | |
| Lead | Lead1:1 | Fully supported | |
| Opportunity | Opportunity1:1 | Fully supported | |
| Pipeline and Stage | Pipeline and Stagelossy | Fully supported | |
| Quote | Quotation1:1 | Fully supported | |
| Order | Sale Order1:1 | Fully supported | |
| Product | Product1:1 | Fully supported | |
| Price List | Pricelist1:1 | Fully supported | |
| Activity: Task, Email, Phone Call, Appointment | Activity1:1 | Fully supported | |
| Note and Attachment | Note and Attachment1:1 | Fully supported | |
| User and Owner | User1:1 | Fully supported | |
| Custom Table | Custom Field or Modellossy | Fully supported | |
| Territory | Sales Team or Taglossy | Fully supported |
Gotchas + challenges
Platform-specific issues from each side, plus the pair-specific challenges that don't show up on either platform's page on its own.
Microsoft Dynamics 365 Sales gotchas
Professional tier 15-table custom table limit blocks migrations
October 2024 pricing increase applies at renewal for all customers
Custom fields must be created in the UI before API writes
Power Platform request limits apply to bulk migrations
Activity records orphaned to inactive owners fail silently
Odoo CRM gotchas
Odoo.sh version gating blocks assisted migrations from trial
Enterprise modules fail to install on Community after database restore
Custom module view inheritance breaks between Odoo major versions
Custom fields risk losing their application context on Community
API access for Community is gated behind the Custom Plan
Pair-specific challenges
Migration approach
Discovery and environment assessment
We audit the source Microsoft Dynamics 365 Sales environment across tier (Professional, Enterprise, Premium), custom table count, active Power Automate flows, pipeline count and stage structure, engagement volume (activity records), price list complexity (currencies, quantity breaks), and any Dataverse tables above the 15-table Professional tier limit. We pair this with an Odoo environment assessment: edition (Community free with in-house hosting versus Odoo Online/Standard at €25+ per user per month), enabled apps (CRM, Sales, Accounting, Inventory), and any existing Odoo configuration that must be preserved. The discovery output is a written migration scope, a custom field inventory, a Power Automate flow inventory, and an Odoo edition recommendation.
Odoo schema pre-build in staging
We coordinate with the customer's Odoo administrator to pre-create all destination custom fields, custom models, stage configurations, sales team structures, and pricelists in a staging Odoo database. This includes creating every Dynamics custom field as an Odoo Studio field with the correct type (Char, Float, Date, Many2one, etc.), defining pipeline stages that match Dynamics stage names and probabilities, and configuring sales teams that map to Dynamics territories or business units. Schema is validated in staging before any production migration begins. We also configure Odoo's Multi-Currency settings if the source uses multiple Price List currencies.
Dataverse bulk export and data extraction
We extract all CRM records from Dynamics 365 using the Dataverse Web API with batch operations and page-size limits (default 5,000 records per page). For large datasets (over 100,000 records), we use the Dataverse bulk export with delta queries to chunk the extraction and avoid timeout. The export runs in phases in dependency order: Accounts, Contacts, Leads, Opportunities, Products, Price List Items, Quotes, Orders, Activities. We flag any records with invalid OwnerId references during extraction and produce an owner reconciliation list for the customer's admin to resolve before the import phase.
Sandbox migration and reconciliation
We run a full migration into the staging Odoo database using production-like data volume. The customer's RevOps lead or Odoo administrator reconciles record counts against the Dynamics source (Accounts in, Companies in; Contacts in, Contacts in; Opportunities in, Opportunities in; Activities in, Activities in), spot-checks 25-50 randomly selected records for field accuracy, and validates that pipeline stage assignments, owner assignments, and monetary values are correct. Any field mapping corrections are applied to the migration scripts at this stage. This is the last validation gate before production migration.
User provisioning and owner reconciliation
We extract every distinct Dynamics User referenced on CRM records (OwnerId) and match by email against the destination Odoo User table. Users without a matching Odoo account are placed in a reconciliation queue, and the customer's Odoo administrator provisions the missing users. Inactive Dynamics owners are mapped to the designated migration administrator or Legacy Owner placeholder. OwnerId references on all record types are resolved against this user map before each import phase. Migration cannot proceed past this step because Opportunity, Activity, and Note records require a valid user_id at insert.
Production migration in record dependency order
We run production migration in strict dependency order: Companies (from Accounts), Contacts (with Company_id resolved), Leads, Opportunities (with Partner_id and user_id resolved, stage mapped to Odoo Stage ID), Products and Pricelists, Quote/Quotation records, Sale Orders, Activity history (Tasks, Emails, Phone Calls, Appointments as Odoo Mail Activity records via XML-RPC), Notes and Attachments. Each phase emits a row-count reconciliation report and a validation summary before the next phase begins. A final delta pass captures any records modified during the migration window.
Cutover, validation, and automation rebuild handoff
We freeze Dynamics 365 record creation during the cutover window, run a final delta migration of any records modified during the window, then enable Odoo as the system of record. We deliver the Power Automate flow inventory document (with Odoo Automated Action equivalents documented per flow) and the Dynamics report list (with Odoo reporting rebuild notes) to the customer's Odoo administrator. We support a two-week hypercare window where we resolve any record reconciliation issues raised by the customer's sales team. Rebuilding Power Automate flows as Odoo Automated Actions, rebuilding Dynamics reports in Odoo, and training sales teams on Odoo navigation are outside the standard migration scope and are handled as separate engagements or internal admin tasks.
Platform deep dives
Microsoft Dynamics 365 Sales
Source
Strengths
Weaknesses
Odoo CRM
Destination
Strengths
Weaknesses
Complexity grading
Standard CRM migration. All 8 core objects map 1:1 between Microsoft Dynamics 365 Sales and Odoo CRM.
Overall complexity
Standard migration
Derived from compatibility, mapping clarity, API constraints, and data volume across Microsoft Dynamics 365 Sales and Odoo CRM.
Object compatibility
All 8 core objects map 1:1 between Microsoft Dynamics 365 Sales and Odoo CRM.
Field mapping clarity
Field mapping is derived from defaults — final spec confirmed during the sample migration.
Timeline complexity
8-object category — typical timelines run 2–7 days end-to-end.
API constraints
Microsoft Dynamics 365 Sales : Per-user and per-environment request limits enforced across Power Platform; exact limits vary by license tier and environment capacity.
Data volume sensitivity
Microsoft Dynamics 365 Sales exposes a bulk API — large-volume migrations stream efficiently.
Estimator
Rule-based pricing — no per-record fees, no manual quotes. Migrations over 2M records are scoped individually.
Step 1
Pick a category, then your source and destination platforms.
Category
FAQ
Answers to the questions buyers ask most during Microsoft Dynamics 365 Sales to Odoo CRM migration scoping. Not seeing yours? Book a call.
Walk through your Microsoft Dynamics 365 Sales to Odoo CRM migration with a real engineer — 30 minutes, free, written quote within 24 hours.
Book a free 30 minute consultationAdjacent paths
Other ways to leave Microsoft Dynamics 365 Sales
Other ways to arrive at Odoo CRM
Ready when you are
Tell us record counts and timeline. We'll come back with a written quote inside 1 business day — no commitment, no sales pitch.