ERP migration
Field-level mapping, validation, and rollback between Odoo Enterprise and Epicor Prophet 21. We move data and schema; workflows are rebuilt natively in Epicor Prophet 21.
Odoo Enterprise
Source
Epicor Prophet 21
Destination
Compatibility
10 of 15
objects map 1:1 between Odoo Enterprise and Epicor Prophet 21.
Complexity
BStandard
Timeline
8-12 weeks
Overview
Moving from Odoo Enterprise to Epicor ERP is a manufacturing-scale migration that restructures both the data model and the operational logic of the ERP. Odoo's unified res.partner contact model (which stores individuals and organizations in one table with a company_type flag) must split into Epicor's separate Person and Company entities. Odoo's product.template and product.product hierarchy must restructure into Epicor's single product model with specific configurations and alternate codes. We extract from Odoo via XML-RPC or direct PostgreSQL read for large datasets, apply schema-aware transformations during a staging phase, and load into Epicor through the Epicor REST API with batch chunking and parent-record lookup resolution. Manufacturing data (Bill of Materials, work orders, routing operations) receives dedicated restructuring because Odoo's BOM-with-routing model does not map directly to Epicor's MES-oriented structure. We do not migrate Odoo Workflows, Odoo Studio automations, or country-specific fiscal localization modules; these require reinstallation and rebuild in Epicor.
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 Epicor Prophet 21, 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
Epicor Prophet 21
Person + Company
1:manyOdoo's res.partner stores both individuals and organizations in a single table with the company_type field distinguishing them. We split during migration: partners with company_type=company become Epicor Company records; company_type=person become Epicor Person records. The original Odoo partner ID is preserved in a custom Epicor field ext_odoo_partner_id__c for cross-reference. Address data (street, city, state, country, zip) migrates to Company addresses or Person addresses depending on entity type. Bank account records migrate to Epicor Payment Methods linked to the appropriate Company.
Odoo Enterprise
res.partner
Epicor Prophet 21
Contact
1:1Individual partners (company_type=person) who serve as sales contacts, purchasing contacts, or customer service contacts migrate to Epicor Contact records linked to the parent Company. We preserve the partner's email, phone, and role/type tags from Odoo category_ids as Epicor ContactType assignments. Odoo's customer_rank and supplier_rank flags map to Epicor Territory assignments for sales routing.
Odoo Enterprise
product.template
Epicor Prophet 21
Part
1:1Odoo product.template defines the base product with name, default_code, type (product/service/consumable), and list_price. We migrate each product.template to an Epicor Part record, using product.template.default_code as Part.PartNum and product.template.name as Part.PartDescription. The product type maps to Part.TypeCode (M=manufactured, K=kit, S=sales stock, P=service). Product categories from Odoo migrate to Epicor Product Groups.
Odoo Enterprise
product.product (variants)
Epicor Prophet 21
Part + PartRev + PartOpr
1:manyOdoo product variants (product.product) inherit from a product.template but carry variant-specific attributes like size, color, or material grade. We migrate each variant to an Epicor Part as a separate Part record with a variant code in PartAlt to track the parent template relationship. The variant attribute values map to Part Selling UOM or PartRestrict per the customer's configuration choice. For manufacturers who use Odoo's product variants for Bill of Materials ingredient sourcing, this splitting is critical for Epicor's PartRev BOM chain.
Odoo Enterprise
mrp.bom
Epicor Prophet 21
PartRev + PartOpr
1:1Odoo Bill of Materials (mrp.bom) with mrp.bom.line components map to Epicor PartRev (BOM revision) and PartOpr (operations/routings) records. Odoo's bom_line.product_id maps to Epicor PartOpr.MaterialPartNum; Odoo's product_qty maps to PartOpr.QtyPer; Odoo operation.workcenter_id maps to Epicor PartOpr.WorkcenterID. Odoo's workcenter resources and cycle times become PartOpr.EstLaborHours and PartOpr.EstRunHours. Multi-level BoMs require recursive PartRev resolution where child BoMs are created as separate PartRev records linked by PartRev.ParentPart.
Odoo Enterprise
stock.quant
Epicor Prophet 21
PartBin
1:1Odoo stock.quant (on-hand inventory by warehouse and location) maps to Epicor PartBin records keyed by Part, Site, Warehouse, Bin, and Lot/Serial number. Odoo's lot_id and lot_number map to PartBin.LotNum; Odoo's serial_number_id maps to PartBin.SerialNumber. We preserve the on-hand quantity, reserved quantity, and inventory value (at standard cost or FIFO cost from Odoo). Quant snapshots are migrated as opening balances; the Epicor inventory cycle count process reconciles physical counts post-go-live.
Odoo Enterprise
sale.order
Epicor Prophet 21
OrderHed + OrderDtl
1:1Odoo sale.order maps to Epicor OrderHed with order lines (sale.order.line) as OrderDtl. Odoo customer (res.partner) resolves to the Epicor Company and Contact via the partner split. Odoo's order state (draft, sent, sale, done, cancel) maps to Epicor OrderHed.OrderStatus. The Odoo warehouse picking policy (pick and ship from specific warehouse) maps to OrderDtl.WarehouseCode and OrderDtl.ShipRegion. Discount percentages and payment terms from Odoo migrate to OrderDtl.DiscountPercent and OrderHed.TermsCode respectively.
Odoo Enterprise
purchase.order
Epicor Prophet 21
POHeader + PODetail
1:1Odoo purchase.order maps to Epicor POHeader with purchase order lines as PODetail. Odoo's supplier partner resolves to Epicor's Vendor record (Company with vendor classification). Odoo's picking_in_policy and invoicing_control map to PODetail.ReceiptType and PODetail.LineTaxes respectively. Odoo's stock.picking (receipts) linked to purchase orders map to Epicor Receipt records against the corresponding PO.
Odoo Enterprise
account.move (invoices)
Epicor Prophet 21
InvcHead + InvcDtl
1:1Odoo posted invoices (account.move with move_type=out_invoice or in_invoice) migrate to Epicor InvcHead and InvcDtl. Odoo's partner_id resolves to Epicor Company/Contact; Odoo's invoice lines map to InvcDtl with part number, quantity, unit price, and tax code. Odoo's fiscal_position tax mapping translates to Epicor Tax Region assignments on the invoice header. Paid invoices migrate with payment records; open invoices migrate as outstanding AR/AP against the matched customer or vendor.
Odoo Enterprise
account.account
Epicor Prophet 21
GLAccount
lossyOdoo's Chart of Accounts entries migrate to Epicor GLAccount records with AccountCode, Description, and AccountType. This is a configuration step rather than a direct record copy because Epicor's Chart of Accounts ships with country-specific structures that must be installed before data loads. We flag each Odoo account code and recommend the nearest Epicor standard account during scoping, and the customer's Epicor partner or admin finalizes the account mapping against the installed localization template.
Odoo Enterprise
project.project
Epicor Prophet 21
Project
1:1Odoo project.project migrates to Epicor Project with project.task records as Epicor ProjectTask under the corresponding Project. Odoo's analytic accounts (account.analytic.account) used for job costing map to Epicor Project with the WBS structure in ProjectTask. Assignee and stage data from Odoo migrate to ProjectTask.Resources and ProjectTask.PhaseID respectively. Odoo's timesheet data (account.analytic.line) migrates as Epicor LaborDtl records linked to the Project and ProjectTask.
Odoo Enterprise
hr.employee
Epicor Prophet 21
EmpBasic
1:1Odoo hr.employee records map to Epicor EmpBasic with employee name, department, job title, and employment status. Odoo's employee contracts (hr.contract) migrate as Epicor Labor records with pay rate information where applicable. Odoo's attendance and leave data (hr.attendance, hr.leave) migrate as read-only historical records in Epicor's Time and Attendance module; active leave balances require manual re-entry or a separate time and attendance migration scope. Odoo's bank account and emergency contact data from employee records migrates to Epicor EmpBasic HR data sections.
Odoo Enterprise
stock.picking
Epicor Prophet 21
JobMtl + JobOper
lossyOdoo stock.picking records (warehouse transfers and deliveries) that are linked to manufacturing work orders migrate as reference data in Epicor's JobMtl (material consumption) and JobOper (operations) context rather than standalone records. Internal transfers between Odoo warehouses map to Epicor PartTran records for audit trail reconstruction. Customer shipments linked to sale orders migrate as Epicor ShipDtl against the corresponding OrderHed.
Odoo Enterprise
ir_attachment
Epicor Prophet 21
DocumentRevision
1:1Odoo stores file attachments in ir_attachment (PostgreSQL db_datas blob or filestore path). We extract both the binary data and the filestore directory tree, reconstruct the file hierarchy, and link documents to Epicor DocumentRevision records via the DocType and External Disk storage path. Linked attachments on sale orders, purchase orders, and invoices attach to the corresponding Epicor entity via DocType linkage rules. PDF attachments from Odoo stock reports and picking lists migrate as document revisions for shop floor reference.
Odoo Enterprise
custom fields and x_custom_model
Epicor Prophet 21
UD fields + Custom Tables
lossyOdoo custom fields created via Odoo Studio or ir.model.fields on standard models (res.partner, product.product, sale.order, etc.) migrate as Epicor User Defined fields (UD fields) on the corresponding Epicor table. Odoo custom model tables (x_custom_model) migrate as Epicor UD Tables with the same field structure. We read the custom model schema via xmlrpc model fields_get, create matching Epicor UD01-UD30 or custom tables, and migrate records preserving all field values and relationships. This step requires the Epicor partner or admin to configure UD field display labels and grid positioning post-migration.
| Odoo Enterprise | Epicor Prophet 21 | Compatibility | |
|---|---|---|---|
| res.partner | Person + Company1:many | Fully supported | |
| res.partner | Contact1:1 | Fully supported | |
| product.template | Part1:1 | Fully supported | |
| product.product (variants) | Part + PartRev + PartOpr1:many | Fully supported | |
| mrp.bom | PartRev + PartOpr1:1 | Fully supported | |
| stock.quant | PartBin1:1 | Fully supported | |
| sale.order | OrderHed + OrderDtl1:1 | Fully supported | |
| purchase.order | POHeader + PODetail1:1 | Fully supported | |
| account.move (invoices) | InvcHead + InvcDtl1:1 | Fully supported | |
| account.account | GLAccountlossy | Fully supported | |
| project.project | Project1:1 | Fully supported | |
| hr.employee | EmpBasic1:1 | Fully supported | |
| stock.picking | JobMtl + JobOperlossy | Fully supported | |
| ir_attachment | DocumentRevision1:1 | Fully supported | |
| custom fields and x_custom_model | UD fields + Custom Tableslossy | 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
Epicor Prophet 21 gotchas
Third-party bolt-on integrations complicate migration scope
Dirty data without standardized processes compounds migration risk
SDK customizations and BPMs may not survive platform upgrades
Report-based export only for non-technical users
Per-user pricing model requires accurate user count before migration planning
Pair-specific challenges
Migration approach
Discovery and Odoo module inventory
We audit the source Odoo Enterprise instance across all installed modules (CRM, Sale, Purchase, Inventory, Manufacturing, Accounting, Project, HR, POS), custom fields, custom models, and third-party Odoo Apps. We extract the Odoo version, PostgreSQL database schema, and active Odoo.sh or self-hosted hosting environment. For Odoo.sh customers, we use XML-RPC for extraction; for self-hosted, we use direct PostgreSQL read with the customer's read-only database credentials. The discovery output is a written migration scope document listing every object to migrate, estimated row counts per object, identified Enterprise-only modules that cannot be migrated, and a fiscal localization configuration inventory.
Epicor schema design and product structure
We design the destination Epicor schema including Part configuration (one Part per Odoo product variant), PartRev for each BoM, GLAccount mapping for the Odoo Chart of Accounts, Company and Person split strategy, and UD field definitions for Odoo custom fields. We work with the customer's Epicor partner or administrator to install the correct country-specific Epicor localization before data load begins. The Epicor schema is validated in a non-production Epicor environment before any production migration is attempted.
Sandbox migration and reconciliation
We run a full migration into the Epicor non-production environment using representative data volume. The customer's operations team reconciles record counts for each migrated object (Company/Person split count vs original Odoo partner count, Part count vs Odoo product.product count, PartBin count vs Odoo stock.quant count), spot-checks 30-50 records per object against the Odoo source, and validates BOM integrity by comparing Epicor PartRev structure against Odoo mrp.bom tree. Schema corrections and mapping refinements happen in the sandbox phase. We do not proceed to production migration until the sandbox reconciliation sign-off is received.
Partner and vendor master reconciliation
We extract all distinct Odoo res.partner records and apply the company/person split logic. Individual partners (company_type=person) are held in a reconciliation queue for Epicor Contact linkage review. We match Odoo partner categories (customer_rank, supplier_rank) against Epicor's Company classification (Customer, Vendor, or both). The customer's Epicor admin confirms the Company/Person linkage tree and approves the split before production import of the master data.
Production migration in dependency order
We run production migration in strict record-dependency order: Companies and Persons first (with Contact linkage), then Parts (product templates and variants as split Part records), then PartRev and PartOpr for BoM structure (after Parts are committed so that PartNum references resolve), then inventory (PartBin after Part and Site are committed), then Orders (Sale and Purchase after Company/Customer and Part are committed), then Invoices, then Projects and ProjectTask, then Employees, then Attachment files. Each phase emits a row-count reconciliation report before the next phase begins. Fiscal positions and tax mapping data are delivered as a configuration document rather than imported as records.
Cutover, validation, and BOM rebuild handoff
We freeze writes to Odoo during cutover, run a final delta migration for any records created or modified during the migration window, then mark Epicor as the system of record. We validate Epicor inventory valuation against Odoo's stock.valuation records and flag any FIFO/standard cost discrepancies for the customer's Epicor admin to review. We deliver the fiscal position and tax mapping configuration inventory, the Odoo custom field to Epicor UD field mapping document, and the Odoo custom model to Epicor UD table mapping document. We do not rebuild Odoo Workflows, automations, or Odoo Studio configurations as Epicor processes; these require rebuild in Epicor's Process Management workbench by the customer's implementation team.
Platform deep dives
Odoo Enterprise
Source
Strengths
Weaknesses
Epicor Prophet 21
Destination
Strengths
Weaknesses
Complexity grading
Standard ERP migration. 2 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 Epicor Prophet 21.
Object compatibility
2 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 Epicor Prophet 21 migration scoping. Not seeing yours? Book a call.
Walk through your Odoo Enterprise to Epicor Prophet 21 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 Epicor Prophet 21
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.