ERP migration
Field-level mapping, validation, and rollback between Odoo Enterprise and Odoo ERP. We move data and schema; workflows are rebuilt natively in Odoo ERP.
Odoo Enterprise
Source
Odoo ERP
Destination
Compatibility
13 of 13
objects map 1:1 between Odoo Enterprise and Odoo ERP.
Complexity
BStandard
Timeline
4-8 weeks
Overview
Moving from Odoo Enterprise to Odoo ERP is typically a version upgrade, a self-hosted transition, or a downgrade from the paid Enterprise tier to the open-source Community edition or a self-managed Odoo instance. Odoo Enterprise stores data in the same PostgreSQL-backed res.partner and product.product models as Community, but carries Enterprise-only modules (CRM Enterprise, POS Enterprise, Documents, Social) whose table references become orphaned when the database is restored on a non-Enterprise instance. We handle this by extracting only the subset of modules with Community equivalents, preserving the full Chart of Accounts with country-matched fiscal localization, and flagging every Enterprise-specific model that will be lost in a downgrade so the customer's admin can decide whether to include it in a scrubbed migration. We do not migrate custom Python modules or third-party Odoo Apps as code; we deliver a written inventory of these for the customer's developers to port. Workflows, Automations, and Odoo Studio configurations are excluded from migration scope.
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.
Why teams make this switch
Leaving
What's pushing teams away
Choosing
What's pulling them in
Object mapping
Each row shows how a Odoo Enterprise object lands in Odoo ERP, including any object-level transformations, lookup resolution, or schema-design dependencies.
Typical mapping — final map is confirmed during the sample migration step.
Odoo Enterprise
res.partner (Contacts / Companies)
Odoo ERP
res.partner
1:1Odoo uses res.partner for both individuals and organizations across all modules. We extract all partner records via xmlrpc or PostgreSQL direct-read, preserving address fields, category tags, bank accounts, and custom fields defined via Odoo Studio or ir.model.fields. The destination res.partner schema is matched field-for-field; no transformation is required beyond type-mapping of any custom field data types. Parent-company relationships (commercial partner linkage) are preserved via the commercial_partner_id and parent_id fields, and partner_id references on every related document (sale orders, invoices, purchase orders) are resolved at migration time.
Odoo Enterprise
product.template + product.product (Products)
Odoo ERP
product.template + product.product
1:1Product templates and their variants migrate as a bundle. We preserve product.category hierarchy, vendor pricelist entries (product.supplierinfo), product routes (make-to-order, dropship via stock.location.route), and product.attribute.value combinations. Bills of Materials and work order routing data (mrp.bom, mrp.routing) are covered in the Manufacturing object. Any Enterprise-only fields (e.g., pos_categ_id from POS Enterprise) are flagged and excluded from Community-compatible imports.
Odoo Enterprise
sale.order (Sales Orders)
Odoo ERP
sale.order
1:1Sale orders are migrated with their order lines (sale.order.line) and linked delivery orders (stock.picking) and invoices (account.move). We preserve the picking state (assigned, done, cancelled) and invoice state (draft, posted, paid) from the source so the destination picks up the order in its current status rather than resetting to draft. The sale_journal_id is remapped to the destination's chart of accounts journal. If the source uses Enterprise-specific sale type workflows, those stages are stripped and mapped to the standard sale order states available in Community.
Odoo Enterprise
purchase.order (Purchase Orders)
Odoo ERP
purchase.order
1:1Purchase orders migrate with their order lines, linked receipts (stock.picking), and vendor bills (account.move). We preserve receipt-to-bill matching which is critical for accounts payable accuracy; the destination account.move record carries the same reconcile linkage to the original purchase order. Picking state and invoice state are preserved. Any Enterprise-specific purchase approval workflows are excluded from migration scope.
Odoo Enterprise
account.move (Invoices and Bills)
Odoo ERP
account.move
1:1Odoo Accounting stores posted invoices, vendor bills, and journal entries in account.move. We handle posted vs. draft records differently: posted invoices migrate with full line-item and tax mapping; draft invoices migrate for completion in the destination. Tax grid mappings and reconciliation records are preserved via account.full.reconcile and account.partial.reconcile where the destination schema supports them. We validate that the destination's tax codes can accept the source tax rates before committing the invoice batch.
Odoo Enterprise
account.account (Chart of Accounts)
Odoo ERP
account.account
1:1Chart of Accounts entries are country-specific via fiscal localization modules. Account codes, types (receivable, payable, expense, revenue), and tax receipt tags must be mapped to the destination's country-matched localization. We use the country localization module of the destination instance to validate that each source account maps to a valid destination account code before importing. Cross-country localization migration is not attempted without explicit remapping of every affected account and tax code.
Odoo Enterprise
account.fiscal.position (Fiscal Positions)
Odoo ERP
account.fiscal.position
1:1Fiscal positions map taxes and accounts based on partner country and VAT number. These are critical for EU VAT compliance and must migrate alongside every invoice and partner record. We validate that the destination's fiscal.position records have matching account.account and account.tax references in the destination localization before committing. If the destination is in a different country from the source, we flag all fiscal positions for admin review and remapping rather than attempting automatic migration.
Odoo Enterprise
project.project + project.task (Projects and Tasks)
Odoo ERP
project.project + project.task
1:1Project and task records migrate with their full hierarchy including sub-tasks, assignees (user_ids), tags (project.tags), stage pipeline configuration, and timesheet entries (account.analytic.line) where applicable. Custom stage logic defined via Odoo Studio or automated actions is excluded from migration scope; we document the stage names and their sequence so the customer's admin can rebuild the pipeline in the destination. Timesheet history is migrated as read-only analytic line records.
Odoo Enterprise
hr.employee (Employees)
Odoo ERP
hr.employee
1:1hr.employee records migrate with contracts (hr.contract), attendance history (hr.attendance), leave allocations (hr.leave.allocation), and payslip history (hr.payslip) as read-only records. Employment status and effective-dated contracts are preserved with their start and end dates. Historical payslip data migrates as read-only to maintain payroll reporting continuity. If the destination uses a different country localization for payroll (e.g., country-specific HR modules), we flag payroll-related fields for admin review before import.
Odoo Enterprise
ir.attachment (Attachments / Documents)
Odoo ERP
ir.attachment
1:1Odoo stores attachments in both the PostgreSQL database (ir_attachment with db_datas) and the filestore directory. We extract both sources, reconstruct the filestore tree on the destination Odoo instance, and relink database attachment records to the reconstructed filestore paths. Large attachment volumes (over 50 GB) require direct filestore extraction rather than xmlrpc transfer due to API overhead. Binary attachments are base64-encoded for transmission and decoded on the destination.
Odoo Enterprise
stock.quant + stock.move + stock.picking (Inventory)
Odoo ERP
stock.quant + stock.move + stock.picking
1:1stock.quant (on-hand quantities), stock.move (transfer history), and stock.picking (picking orders) migrate with lot and serial number traceability preserved. Warehouse-specific quants are mapped to the destination warehouse configured in the destination Odoo instance. Quant snapshots are migrated as of a defined cutover date; in-transit moves are flagged for the customer's inventory team to reconcile after go-live. Stock valuation records (account.move lines tied to stock moves) are migrated only if the destination accounting localization supports the same valuation method.
Odoo Enterprise
mrp.bom + mrp.routing (Manufacturing / BoM)
Odoo ERP
mrp.bom + mrp.routing
1:1Bill of Materials and work orders migrate via the mrp module models with routing operations, workcenter assignments, and consumption tracking preserved. We verify that the destination Odoo instance has the Manufacturing module installed before migration; if it does not, BoM and routing data is excluded from scope and flagged in the migration inventory. Enterprise-specific manufacturing features (such as mrp_workorder_module dependencies) are flagged as Enterprise-only and excluded.
Odoo Enterprise
Custom Models (x_custom_model via ir.model)
Odoo ERP
Custom Models
1:1Custom models created via Odoo Studio or ir.model fields are fully accessible via xmlrpc model fields_get and standard CRUD endpoints. We migrate custom model records with all field types including relational fields (many2one, one2many, many2many), which require pre-creation of the destination custom model schema before data import. The destination custom model must be created in the destination Odoo instance first; we do not create destination schema via migration scripts. Lookup dependencies are resolved at migration time against the destination's existing record set.
| Odoo Enterprise | Odoo ERP | Compatibility | |
|---|---|---|---|
| res.partner (Contacts / Companies) | res.partner1:1 | Fully supported | |
| product.template + product.product (Products) | product.template + product.product1:1 | Fully supported | |
| sale.order (Sales Orders) | sale.order1:1 | Fully supported | |
| purchase.order (Purchase Orders) | purchase.order1:1 | Fully supported | |
| account.move (Invoices and Bills) | account.move1:1 | Fully supported | |
| account.account (Chart of Accounts) | account.account1:1 | Fully supported | |
| account.fiscal.position (Fiscal Positions) | account.fiscal.position1:1 | Fully supported | |
| project.project + project.task (Projects and Tasks) | project.project + project.task1:1 | Fully supported | |
| hr.employee (Employees) | hr.employee1:1 | Fully supported | |
| ir.attachment (Attachments / Documents) | ir.attachment1:1 | Fully supported | |
| stock.quant + stock.move + stock.picking (Inventory) | stock.quant + stock.move + stock.picking1:1 | Fully supported | |
| mrp.bom + mrp.routing (Manufacturing / BoM) | mrp.bom + mrp.routing1:1 | Fully supported | |
| Custom Models (x_custom_model via ir.model) | Custom Models1:1 | 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.
Odoo Enterprise gotchas
Enterprise-to-Community downgrade leaves orphaned module references
25% legacy surcharge for older Odoo versions
XML-RPC API lacks public rate limit documentation
Official upgrade service ignores custom and third-party modules
Fiscal localization modules tie accounting data to country
Odoo ERP gotchas
No rollback for CSV imports
External ID conflicts on re-import
Many2many field encoding in CSV imports
Large export timeouts require batching
Version schema drift between Odoo releases
Pair-specific challenges
Migration approach
Discovery and version audit
We audit the source Odoo Enterprise instance across Odoo version, installed modules, custom models (ir.model), third-party Apps, and Enterprise-only module usage. We extract the module list via xmlrpc or PostgreSQL ir_module_module query, identify every module that has no Community equivalent, and flag these as data-loss candidates in the written scope document. We also assess data quality by sampling partner records, product counts, open order volumes, attachment file sizes, and historical journal entry age. The discovery output is a written migration scope, a data loss inventory for Enterprise-only modules, and a destination Odoo version and hosting recommendation.
Destination schema design and localization check
We design the destination schema by matching the source's chart of accounts, fiscal positions, and tax codes to the destination's country-matched localization module. We pre-create any custom models and custom fields in the destination Odoo instance before data import begins. If the destination is in a different country than the source, we flag all fiscal position and tax mappings for admin-level remapping rather than attempting automatic migration. For self-hosted destinations, we verify that the destination PostgreSQL instance has adequate storage and network access for the migration workload.
Sandbox migration and reconciliation
We run a full migration into a staging or sandbox destination Odoo instance using production-equivalent data volume. The customer's Odoo administrator reconciles record counts (partners in, products in, orders in, invoices in, project records in), spot-checks 25-50 records against the source for field-level accuracy, and validates fiscal position and tax code mappings. Any mapping corrections, custom field additions, or Enterprise-only table exclusions are resolved in this phase. Sandbox sign-off from the customer's admin is required before production migration begins.
Migration script development with chunking and backoff
We build ETL scripts that extract from the source Odoo Enterprise instance via xmlrpc (for Odoo Online or Odoo.sh) or PostgreSQL direct-read (for self-hosted), transform records to match the destination schema, and load via xmlrpc into the destination. Scripts implement batch chunking at 500 records per batch, exponential backoff with jitter on HTTP 503 responses, and parent-record lookup resolution so that foreign key references (account_id on invoice lines, product_id on order lines, partner_id on projects) are satisfied at the moment of insert rather than via post-import reconciliation. Custom model records are migrated last after all standard object dependencies are resolved.
Production migration in dependency order
We run production migration in record-dependency order: Chart of Accounts and Fiscal Positions (account.account, account.fiscal.position, account.tax), Partners (res.partner), Products (product.template, product.product, product.category), Inventory (stock.warehouse, stock.location), Sales Orders (sale.order with picking and invoice links), Purchase Orders (purchase.order with receipt and vendor bill links), Invoices (account.move), Projects and Tasks (project.project, project.task), Employees (hr.employee with contracts and attendance), Custom Models (x_custom_model), Attachments (ir_attachment with filestore reconstruction). Each phase emits a row-count reconciliation report before the next phase begins. We freeze source writes during cutover and run a final delta migration of any records modified during the window.
Cutover, validation, and workflow rebuild handoff
We validate the destination against control totals from the source: partner count, product count, open order balance, posted invoice total, and inventory quant values as of cutover date. We deliver the written inventory of Enterprise-only modules and custom modules that were excluded from migration scope, along with a rebuild recommendation document for the customer's developers. We do not rebuild custom Python modules, automations, or Odoo Studio configurations; these require the customer's developers to port. We support a one-week hypercare window where we resolve any data reconciliation issues raised by the customer's team after go-live.
Platform deep dives
Odoo Enterprise
Source
Strengths
Weaknesses
Odoo ERP
Destination
Strengths
Weaknesses
Complexity grading
Standard ERP migration. 1 of 8 objects need a mapping; the rest are 1:1.
Overall complexity
Standard migration
Derived from compatibility, mapping clarity, API constraints, and data volume across Odoo Enterprise and Odoo ERP.
Object compatibility
1 of 8 objects need a mapping; the rest are 1:1.
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
Odoo Enterprise: Not publicly documented; timeouts observed on Odoo.sh at high request volumes.
Data volume sensitivity
Odoo Enterprise doesn't expose a bulk API — REST + parallelization used for high-volume runs.
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 Odoo Enterprise to Odoo ERP migration scoping. Not seeing yours? Book a call.
Walk through your Odoo Enterprise to Odoo ERP migration with a real engineer — 30 minutes, free, written quote within 24 hours.
Book a free 30 minute consultationAdjacent paths
Other ways to leave Odoo Enterprise
Other ways to arrive at Odoo ERP
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.