Migrate from Dynamics 365 Sales to Odoo: what the move involves
Moving from Dynamics 365 Sales to Odoo is a data, process and cutover project, and the scope is larger than a CRM swap. Most teams arrive here at a renewal, after a licensing change, because a data residency review flagged where customer records sit, or because they want to reduce dependence on one vendor. Those reasons are legitimate, and the migration plan should start by writing down which of them drives the decision, since that determines how much of the Microsoft estate has to move at the same time. Internal administrators usually own the project, with an implementation partner handling the technical extraction, import scripts, testing and hardening of the new server.
The effort and risk depend less on record counts than on how much of the business runs through the surrounding tools. Odoo's CRM app sits in the same suite as sales, invoicing and inventory, so a team that also leaves Microsoft finance tools has to decide which Odoo apps replace which systems before any data moves. That decision changes the scope from one CRM dataset to several linked ones, including products, price lists, invoices and stock. Odoo's pricing page indicates that multi-company, Odoo Studio, external API access and custom modules are limited to the Custom plan, so confirm with Odoo which features the target edition needs before you design the data model. Also confirm your edition choice, because the Community and Enterprise editions differ in the upgrade service and in support.
Which Dynamics 365 Sales capabilities map to Odoo, and which need rework
This table maps the main Dynamics 365 Sales capabilities to Odoo CRM and its sales, invoicing and inventory apps. Read the status column as a first pass: clean means a standard Odoo app covers the need, needs rework means the logic must be rebuilt, and gap means no direct equivalent exists. Confirm each Odoo entry against your own edition and hosting tier before you commit.
| Capability | Odoo equivalent and what to confirm | Status |
|---|---|---|
| Accounts and contacts | Odoo CRM partner records with contact hierarchies. Confirm the import template and custom fields your edition allows. | Clean |
| Opportunities and pipeline | Odoo CRM pipeline stages and kanban views. Map Dataverse status reasons to Odoo stages before loading. | Needs rework |
| Products and price lists | Odoo Sales product catalog and pricelists. Confirm how variants and multi-currency pricing are handled in your version. | Needs rework |
| Quotes and orders | Odoo Sales quotations that convert to sales orders. Rebuild approval rules and quote templates by hand. | Needs rework |
| Invoicing | Odoo Invoicing app, which requires the accounting setup for your country. Confirm local tax and e-invoicing support with the vendor. | Needs rework |
| Activities and email tracking | Odoo activities and chatter on records. Confirm whether your mail setup logs Microsoft 365 email automatically. | Needs rework |
| Reporting | Odoo pivot, graph and list views with filters. Confirm the dashboard and export options available in your edition. | Needs rework |
| Workflow automation | Odoo automated actions for simple triggers. Confirm whether Studio and custom modules are included in your plan. | Gap |
| Outlook and Entra ID sign-in | Odoo supports LDAP authentication in its documentation. Confirm Entra ID sign-in and Outlook integration for your edition. | Gap |
Which Dataverse data can be exported and how
These cards cover the export paths Microsoft provides, the table settings that decide what reaches the lake, the records to map into Odoo, and the Microsoft connections users depend on. Start with a table inventory, because it sets the scope of every later step. Confirm limits and table requirements in your own tenant before you build the import.
Excel exports from views
Dataverse lets users export the rows of a saved view to Excel. This suits a single account list or a pipeline snapshot, but the file only carries the columns and rows the view shows, so it cannot serve as a full migration extract. Check the row and file size limits in your environment, and use the export to confirm record counts against the full extract.
Azure Synapse Link table copies
Azure Synapse Link copies Dataverse tables to an Azure data lake as CSV files, which gives you a complete table-level extract for the Odoo import. A Power Platform administrator and an Azure subscription you control are needed to set it up. Confirm the current file format, refresh behavior and running cost in Microsoft's documentation, and extract before any Dynamics 365 license changes, since this copy is your fallback for closed records and custom entities.
Change tracking on each table
Synapse Link only exports tables that have change tracking enabled, so a missing table usually points to a configuration gap. List every entity in scope, including custom tables for quotes, price lists and product families, and check each one against Microsoft's current table requirements. Record the result in the migration plan so reviewers can see that each table was verified before the extract ran.
Accounts, contacts, opportunities and products
Map Dataverse accounts and contacts to Odoo partners, opportunities to Odoo CRM opportunities, and products and price lists to Odoo sales products and pricelists. Import parent records first, so contacts link to companies and opportunities link to their customers. Odoo imports from CSV templates in list views, so confirm field names and external IDs for your version. Load into a test copy of the database first, using Odoo's duplication with neutralization.
Owners, teams and activity history
Dataverse owners can be system users, teams or business units, and each must resolve to an Odoo user before records load. Map every owner before loading, and decide how inactive users are handled: deactivate, reassign, or keep as archived owners. Activities such as tasks, calls and appointments usually map to Odoo activities, but confirm which activity types your extract includes and how notes and attachments are stored.
Outlook, Entra ID and Microsoft 365 mail
Outlook add-ins and email tracking are tied to Dataverse, so plan their replacements before cutover. Odoo supports LDAP authentication, described in its Odoo LDAP guide. Test it against your directory, and confirm whether it can serve Entra ID sign-in for your version before you rely on it. Configure Microsoft 365 mailbox and calendar sync for each user group and test it with pilot users.
Choosing Odoo edition and hosting before the data moves
Decide the Odoo edition and hosting model before you export a single record, because the answer changes what you can build and who you pay. The Community edition is published under LGPL-3.0 and can be installed and run without a license fee. The Enterprise edition adds features and support, but its source code is not publicly available and it requires a subscription or partner access. Treat the edition as a scoping decision, not a detail to settle at go-live. Hosting and feature access are tied together in Odoo's pricing. According to the Odoo pricing page, only the Custom plan can be hosted on Odoo.sh or on-premise, and only Custom includes multi-company, Odoo Studio, external API access and custom modules. If your migration depends on pushing deals from integrations, running several legal entities or shipping custom modules, confirm that these requirements fit the Custom plan before you commit to a hosting model. Ask Odoo to confirm current plan contents in writing, because pricing pages change.
On-premise Enterprise is activated by entering a subscription code in the database, and the upgrade service that moves a database to a newer supported version also requires an Enterprise subscription. The Community edition has no access to that service, so your team would carry every upgrade and test in-house. Under the standard support terms, security updates and bug fixes apply during the standard support window, and Odoo's documentation describes paid extended support as limited to Odoo.sh for select versions and on-premise. Confirm which version you will launch on, the end of its standard support, and whether your integrations need Enterprise-only modules before the data moves, so the cutover plan does not assume capabilities you have not licensed.
How the migration runs from inventory to decommission
The sequence moves Dynamics 365 Sales data and processes into Odoo in controlled stages, with each stage closed by a written output the sales and finance owners can check. It keeps the old system available as a reference until the cutover is signed off.
Inventory Dataverse tables and business processes
List every Dataverse table the sales team uses, including accounts, contacts, opportunities, quotes, orders, invoices, products, price lists and activities, plus any custom entities, business process flows, workflows and Power Automate flows that touch them. Record the owner, record volume and the people who depend on each item. Confirm with your Microsoft administrator which tables are reachable for full copies and which need a different extraction route. The output is a field mapping sheet draft and an inventory register signed off by the sales operations lead.
Pilot with one sales team and a sample of records
Choose one sales team and a representative sample of accounts, open opportunities and closed deals. Load the sample into a non-production Odoo CRM database, then map it to Odoo's contact, lead, opportunity, product and quote models. Have the team work the sample for a fixed review period agreed in your project plan and log every field that loses data or formatting. The output is a pilot defect log and an updated field mapping sheet that the team has approved.
Rebuild quote-to-invoice in Odoo apps
Configure the Odoo apps your finance and fulfillment teams will use, which typically means Sales, Invoicing and, where needed, Inventory, with products, taxes, price lists, payment terms and document templates carried over from your Dynamics quote and invoice formats. Check which of these apps your chosen edition and plan include before you commit to a design. Walk one quote through to a posted invoice and a payment in the test database. The output is a signed design note and a test invoice set that finance has reconciled.
Run a parallel test with neutralized database copies
Duplicate the production Odoo database to create test copies, using the duplication and neutralization method described in Odoo's on-premise documentation so that outbound emails and payment or integration connections cannot reach customers. Load a full extract from Dataverse into one copy and run both systems side by side for a set period agreed in advance. Compare record counts, pipeline totals, open quote values and invoice totals each day. The output is a reconciliation report with every difference explained or fixed and accepted by the business owner.
Cut over with a final delta export
Freeze new entry in Dynamics 365 for the cutover window, run a final delta export of records changed since the last full extract, and load it into production Odoo. Repeat the reconciliation on the frozen data, then switch user access and single sign-on for Odoo to production. Confirm that users can reach Odoo through your identity provider and that Outlook or email connections are repointed as planned. The output is a signed cutover checklist that names the approver for each item and records the time the freeze began and ended.
Decommission Dynamics 365 access and exports
After the cutover is accepted, keep a read-only archive copy of the Dataverse extracts, stored under your retention rules, and remove user licenses and security roles that are no longer needed. Confirm with your Microsoft contract owner which subscription, Power Platform and Copilot licenses end and when, using the terms in your agreement. Revoke app registrations and service connections that still point at Dataverse. The output is a decommission record that lists each license removed, each connection revoked and where the archive is held.
What drives migration cost and duration
This table lists the factors that move the effort of a Dynamics 365 Sales to Odoo migration up or down, why each one matters, and how to reduce it. No price or duration is given here, because both depend on the written scope. Use the table to prepare the requirements you send for a fixed-scope quote.
| Driver | Why it changes cost or effort | How to keep it down |
|---|---|---|
| Custom entities and business process flows | Each custom Dataverse table or process flow needs a mapped Odoo model, fields, stages and rules, and each one must be tested. Custom logic in plug-ins or flows is often rebuilt rather than copied. | Inventory every custom table and flow before scoping. Retire unused ones, and map the rest to standard Odoo CRM stages where the business allows. |
| Volume of history, attachments and activities | Large histories increase extraction, cleansing, deduplication and import runs. Attachments and notes need a separate path, and many imports mean more reconciliation. | Agree a cutoff date for closed records. Decide which attachments must move and which stay in the archive. |
| Number of integrations | Connections to Outlook, Microsoft 365, ERP, marketing or support tools each need design, credentials, testing and monitoring. Odoo integrations often use its API or connectors built for your scope. | List every system that reads or writes CRM data. Rank them by business need and phase the lower-priority ones after cutover. |
| Number of Odoo apps in scope | Adding Sales, Invoicing, Inventory or Accounting increases configuration, product and tax setup, and user testing. Each app brings its own data model and approval rules. | Start with CRM and the minimum apps needed to quote and invoice. Add the rest in later phases once the core process is stable. |
| Edition and hosting choice | The Community edition is LGPLv3 licensed, while the Enterprise edition is separately licensed. The Odoo pricing page lists only the Custom plan for Odoo.sh or on-premise hosting, and only Custom includes multi-company, Odoo Studio, external API access and custom modules. Those features can change scope and cost. Upgrade service access also depends on the Enterprise subscription. | Confirm which features you need before choosing an edition. Ask each vendor or partner to state the subscription terms in writing, and compare hosting costs with your own infrastructure. |
| Finance tool migration | Moving invoicing, ledgers, tax and payment data away from Microsoft finance tools adds reconciliation, opening balances and parallel runs. This work often runs longer than the CRM import itself. | Agree which finance records move and which stay in the old system. Set a cutover date for the ledger separately from the CRM. |
| Number of users to train | Each role, such as sales, sales management, finance and support, needs training material and sessions. Users who relied on Dataverse views or Outlook add-ins need new workflows. | Build role-based training from the agreed process map. Train a small group of champions who support colleagues after go-live. |
| Data quality and ownership decisions | Duplicate accounts, inconsistent owners and missing fields slow the import and need decisions from business owners. Each open question adds review cycles. | Assign a named business owner for each data domain. Clean the source data before the final extraction, not during the import. |
| Parallel running and cutover window | Keeping Dynamics 365 and Odoo in use at the same time requires sync rules or double entry. A longer window increases testing and support effort. | Define a short freeze period and a rollback plan. Ask for the sync approach and its effort in the written scope. |
What usually goes wrong when moving to Odoo
Most failed Dynamics 365 Sales to Odoo moves fail in the data, not the software. The cards below cover the risks we see most often, each with the check that prevents it. Work through them before the first production import and again before cutover.
Incomplete exports from views
Excel exports from Dynamics 365 views are capped by size and only carry the columns the view shows, so a view that looks complete can silently drop rows. Export full tables instead, using a method that copies every record, and compare row counts per table against Dataverse before importing anything. Illustrative check: if a view shows 4,000 opportunities but the table holds 6,200, the view is not your source.
Lost activity history
Emails, calls, meetings and tasks often sit in linked activity tables rather than on the account or opportunity record, so a basic contact import keeps the company but loses the conversation trail. Decide which activity types must move, map them to Odoo's chatter and activities, and confirm with sales leads which history they will need on day one. Keep the original Dataverse extract as the archive of record.
Duplicate contacts across accounts
Dynamics often holds the same person under several accounts, and Odoo treats contacts and companies differently, so a naive import creates duplicate partners and splits open deals across them. Run deduplication on email and tax ID before import, define which record is the master, and agree the merge rules with the sales team. Confirm how Odoo's partner hierarchy will represent your account structure.
Mismatched product and price data
Dynamics price lists, units of measure and product families rarely map one to one onto Odoo's product templates, variants and pricelists. A quote that prints the wrong price or unit is a commercial error, not a data error, so reconcile the product catalog and each price list against signed quotes before go-live. Ask a finance owner to sign off the product master.
Quote numbering and tax errors
Sequence numbers, tax rules and fiscal positions must be configured in Odoo before any quote or invoice is issued, and historical document numbers must not collide with new ones. Set up sequences and tax mappings in a test database, issue sample quotes and invoices, and have finance verify totals and tax lines against the existing system. Ask your accountant which tax rules apply in your jurisdiction.
Cutover without a final delta
Teams often import a full extract weeks before go-live and then stop, so records changed in Dynamics after the extract never reach Odoo. Plan a final delta export on the cutover date, reconcile counts and totals, and freeze edits in Dynamics for the window. Odoo's upgrade documentation notes that major versions on Odoo Online and Odoo.sh are mandatory every two years, and Odoo 17.0 standard support has ended, so target a supported release such as 19.0 or later and confirm the current version with Odoo before you build.
How the move differs by company size and starting point
This is the narrowest move. The team replaces Dynamics 365 Sales for accounts, contacts, leads and opportunities, while invoicing, ledgers and purchasing stay in Microsoft finance tools. Odoo CRM can run on its own, but the boundary with the finance system must be defined early, because customer and product identifiers will exist in two places. Scope is mostly sales data and the Outlook and Microsoft 365 habits that users rely on. Testing focuses on record counts, owner assignment and pipeline reports. A parallel run can be shorter because no ledger balances change hands, though the sync between the two systems must be tested as carefully as the data itself.
- Identifier mapping: Agree how Dataverse account IDs map to Odoo partner records and keep the mapping table as a migration artifact.
- Finance boundary: Decide which fields, such as customer numbers and payment terms, are owned by the finance system and which by Odoo.
- Integration testing: Confirm what Microsoft finance tools read from CRM data and test those reads against Odoo output.
- Shorter parallel run: Compare pipeline totals and activity counts for a defined period rather than running both systems for every workflow.
- Scope control: Leave Copilot-generated content, Power Platform flows and unused entities out unless a named user needs them.
Before committing, confirm with the finance team which Microsoft tools must keep reading customer data and how each read will be replaced or retained.
Here the team moves CRM and also brings quoting, invoicing and inventory into one Odoo database. This is a larger migration because quote-to-invoice becomes a process that Odoo must run end to end, not a field handoff. Product catalogs, price lists, tax settings and open invoices need careful transfer, and users must relearn order handling. Testing covers complete order cycles, from opportunity to delivered and invoiced order, and should include partial deliveries and credit notes. The parallel run is longer because a sales order that starts in one system and finishes in the other causes errors that are hard to reconcile.
- Product and price data: Clean SKUs, units of measure and price lists before import, since these are harder to correct after orders reference them.
- Open transactions: Decide whether open quotes and unpaid invoices move as historical records, as live documents, or stay in Microsoft until they close.
- End-to-end test scripts: Write scripted order cycles covering discounts, taxes, returns and multi-line orders.
- Longer parallel run: Run new orders only in Odoo after a cutover date and keep the old system read-only for lookups.
- Role changes: Confirm who approves quotes, who issues invoices and who adjusts stock, since these roles may change with the new suite.
Confirm with the Odoo edition you plan to use which apps and features are included, since the pricing page separates plans and the Community edition has no upgrade service.
A group with several legal entities has a different problem. Each company may have its own chart of accounts, currencies, pipelines and sales teams, and records may be shared across entities. Odoo's multi-company features are documented as part of the Custom plan on the pricing page, so the edition choice is driven by this requirement before any data is touched. Scope includes entity structure, record ownership rules and intercompany customers. Testing must check that users see only the records their entity allows and that shared customers are not duplicated across companies. Each entity may need its own cutover date, which extends the overall programme.
- Edition check: Confirm multi-company, Odoo Studio, external API access and custom modules are included in the plan you buy before design work begins.
- Entity-by-entity scope: Decide whether all entities move at once or in waves, and document the order.
- Access testing: Test record rules for each role in each company, including users who belong to more than one entity.
- Shared customer records: Define how a customer that buys from several entities is represented.
- Staggered parallel runs: Plan separate run periods for each entity, with reporting that consolidates results during the overlap.
Ask the vendor to confirm the current feature list for the Custom plan in writing, because plan contents are the basis for both the design and the cost.
Organizations on Dynamics 365 Customer Engagement (on-premises) start from a different data model and a different timetable. Exports may come from an on-premises database rather than a cloud Dataverse environment, and customizations, plug-ins and reports may be heavier. The migration window is set by the support lifecycle of the current system, so planning starts with the end-of-support dates for that version. Scope usually includes more custom entities and more history, which must be classified as keep, archive or drop. Testing should compare record counts per entity against the source database, since on-premises schemas often contain fields that no one uses.
- Source inventory: List custom entities, plug-ins, workflows and reports, and mark which ones have an equivalent in Odoo.
- History decisions: Set rules for archiving closed opportunities and activities older than a cutoff, and record who approved them.
- Reconciliation: Compare record counts and key totals per entity against the source before each test cycle.
- Window planning: Work backward from the support end date to set test, cutover and rollback milestones.
- Hosting decision: Confirm early whether the target stays on your own servers, which affects the Odoo deployment method and the backup plan.
Confirm the exact support dates for your version with Microsoft, because they determine how much time the migration has.
Questions teams ask before moving from Dynamics 365 Sales to Odoo
What drives the cost of moving from Dynamics 365 Sales to Odoo?
The cost depends mostly on how much data and process logic must move, and who does the work. The main components are discovery and mapping of Dataverse tables to Odoo models, data extraction and cleansing, configuration of the CRM, sales, invoicing and inventory apps, custom development for anything Dynamics handles with plug-ins or Power Automate flows, hosting and database administration, testing, cutover, and training. Each component is paid to a different party: your staff time, your hosting provider, Odoo for any Enterprise subscription, and an implementation partner if you hire one. Ask any quote to split one-time work from recurring hosting, support and upgrades, and to state which Odoo edition it assumes.
How long does a Dynamics 365 to Odoo migration usually take?
Duration is set by the number of custom entities, the volume of history you keep, how many Dynamics workflows must be rebuilt, and how many finance processes move with the CRM. Teams with a clean account and opportunity model and a short list of quote templates usually finish faster than teams with heavily customized Dataverse solutions. Plan for at least one full test migration into a non-production Odoo database, a parallel run, and a defined cutover window. We do not publish durations; ask for a timeline that lists the phases, the decision points and the acceptance criteria before work starts.
What do we need from our own team during the migration?
You need named owners who can make decisions quickly, because most delays come from unresolved questions about stages, pricing rules and approval steps. Expect to provide a sales operations lead who understands the current pipeline, a finance contact who signs off on invoice numbering, tax treatment and chart of accounts, an IT contact for identity, DNS and hosting access, and power users who test quotes and orders. Your team also needs to decide what history to keep, which records to archive, and which users get access on day one.
Can our own staff complete the migration without an implementation partner?
Yes, a team with Odoo and database administration skills can do it, but the work is more than an import. Staff must export complete tables from Dataverse, map fields and relationships, load customers, opportunities and products in the right order, rebuild quote-to-invoice in Odoo's apps, and document the result. Consider a partner if your team has no one who can run PostgreSQL backups, manage upgrades or test integrations. Odoo's upgrade documentation notes that on-premise upgrades depend on an Enterprise subscription, so plan that ownership before you commit.
Do we need Odoo Community or Enterprise for our integrations?
Check each integration before choosing an edition. The Community edition is published under LGPL-3.0 and covers the CRM app with the sales and invoicing apps you need for many teams. Odoo's pricing page states that only the Custom plan can be hosted on Odoo.sh or on-premise, and that multi-company, Odoo Studio, external API access and custom modules are included only in Custom. Confirm with Odoo whether your Microsoft 365, identity or finance connectors depend on Enterprise features, and ask for the edition, support terms and upgrade path in writing.
What happens to our Dynamics data after cutover?
After cutover, Dynamics 365 Sales remains a separate system until your subscription ends, so you should decide the retention period, export a final full copy and store it under your own controls. Keep the exported files, the mapping documents and the reconciliation reports together so auditors or legal teams can trace records. Confirm with Microsoft what happens to your Dataverse environment when the subscription ends, and remove access for users who no longer need it. Your migration plan should include a documented deletion or archive step, approved by the data owner.
How DeployOpen scopes, runs and supports the Odoo migration
DeployOpen plans, implements, integrates, hardens, backs up and documents self-hosted Odoo inside your own infrastructure, whether that is your cloud account, a data center or an air-gapped network. Most engagements are fixed-scope, so the scope, deliverables and timelines are agreed in writing before any work starts. For this migration, that written scope should name the Dataverse tables in question, the Odoo apps in use (CRM, Sales, Invoicing, Inventory and any others), the edition decision between Community and Enterprise, the user groups that will need access, and the cutover approach. Because a quote follows from that written scope, the more precisely the scope lists these items, the more closely the quote reflects the work.
Expect the written scope to cover the parts that are easy to underestimate: the data extraction from Dataverse, the mapping and cleansing of accounts, contacts, opportunities and products, the rebuild of quote-to-invoice flows in Odoo's apps, identity integration, and the test copies used for validation. Ask for the deliverables to be listed individually, including the mapping specification, the import scripts or procedures, the test sign-off criteria, the runbook, the backup and restore procedure and the handover documentation. Also confirm which items your own staff will perform, such as sign-off on field mappings and user acceptance testing, because those hours are part of your internal effort regardless of who runs the technical work.
Ongoing support, upgrades and continuous testing are available as retainers after go-live, and they matter for Odoo in particular. Odoo's standard support window, the release cadence and the mandatory upgrade rules on its hosted options all affect how often you will need to plan an upgrade, so ask for the retainer to cover upgrade testing against an upgraded test database before any production change. Confirm with Odoo which support and subscription terms apply to your chosen edition, since those are not part of DeployOpen's scope. When you request a quote, ask for the written scope, the list of deliverables and the assumptions behind them, and ask which items are one-time and which recur under a retainer.

