ERP migration

Migrate from Odoo Enterprise to Epicor Prophet 21

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 logo

Odoo Enterprise

Source

Epicor Prophet 21

Destination

Epicor Prophet 21 logo

Compatibility

67%

10 of 15

objects map 1:1 between Odoo Enterprise and Epicor Prophet 21.

Complexity

BStandard

Timeline

8-12 weeks

Rollback included Accuracy guarantee Field-level validation

Overview

What this migration involves

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.

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

Odoo Enterprise logo

Odoo Enterprise

What's pushing teams away

  • Per-user, per-month pricing compounds at scale: a 50-user team on the Standard plan pays roughly $1,500/month before implementation, customization, or partner support costs.
  • Customization requires qualified Odoo developers (Python, ORM) and becomes the largest ongoing expense after initial implementation, with hidden maintenance costs when upgrading custom code.
  • Country-specific fiscal localizations lack clear documentation; tax mapping and fiscal positions require deep Odoo expertise to configure correctly and consistently.
  • Support responsiveness is inconsistent; business-critical issues have been reported as taking days to escalate, creating continuity risk for ERP-dependent operations.
  • Per-app billing means enabling additional modules to unlock functionality that should be core creates sticker shock; full ERP capability requires many paid apps.

Choosing

Epicor Prophet 21 logo

Epicor Prophet 21

What's pulling them in

  • Industry-specific design for wholesale distributors, not a general-purpose ERP repurposed for distribution — distributors choose P21 because it matches their replenishment, kitting, and counter-sale workflows out of the box.
  • Strong inventory control with automated replenishment, lot and serial tracking, and multi-warehouse management appeals to distributors with complex stock requirements and tight margin pressure.
  • Responsive customer support cited across G2 and Gartner reviews, with Epicor's 90% retention rate reflecting long-term customer satisfaction in a market where switching costs are high.
  • Cloud deployment on Microsoft Azure provides the flexibility to scale user counts and warehouse locations without on-premise infrastructure investment.
  • The Software Development Kit lets distributors personalize P21 to their specific business processes without modifying the application source code, preserving upgrade paths.

Object mapping

How Odoo Enterprise objects map to Epicor Prophet 21

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

maps to

Epicor Prophet 21

Person + Company

1:many
Fully supported

Odoo'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

maps to

Epicor Prophet 21

Contact

1:1
Fully supported

Individual 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

maps to

Epicor Prophet 21

Part

1:1
Fully supported

Odoo 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)

maps to

Epicor Prophet 21

Part + PartRev + PartOpr

1:many
Fully supported

Odoo 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

maps to

Epicor Prophet 21

PartRev + PartOpr

1:1
Fully supported

Odoo 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

maps to

Epicor Prophet 21

PartBin

1:1
Fully supported

Odoo 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

maps to

Epicor Prophet 21

OrderHed + OrderDtl

1:1
Fully supported

Odoo 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

maps to

Epicor Prophet 21

POHeader + PODetail

1:1
Fully supported

Odoo 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)

maps to

Epicor Prophet 21

InvcHead + InvcDtl

1:1
Fully supported

Odoo 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

maps to

Epicor Prophet 21

GLAccount

lossy
Fully supported

Odoo'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

maps to

Epicor Prophet 21

Project

1:1
Fully supported

Odoo 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

maps to

Epicor Prophet 21

EmpBasic

1:1
Fully supported

Odoo 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

maps to

Epicor Prophet 21

JobMtl + JobOper

lossy
Fully supported

Odoo 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

maps to

Epicor Prophet 21

DocumentRevision

1:1
Fully supported

Odoo 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

maps to

Epicor Prophet 21

UD fields + Custom Tables

lossy
Fully supported

Odoo 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.

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.

Odoo Enterprise logo

Odoo Enterprise gotchas

High

Enterprise-to-Community downgrade leaves orphaned module references

High

25% legacy surcharge for older Odoo versions

Medium

XML-RPC API lacks public rate limit documentation

Medium

Official upgrade service ignores custom and third-party modules

Medium

Fiscal localization modules tie accounting data to country

Epicor Prophet 21 logo

Epicor Prophet 21 gotchas

High

Third-party bolt-on integrations complicate migration scope

High

Dirty data without standardized processes compounds migration risk

Medium

SDK customizations and BPMs may not survive platform upgrades

Medium

Report-based export only for non-technical users

Low

Per-user pricing model requires accurate user count before migration planning

Pair-specific challenges

  • Odoo res.partner is not Epicor Company or Person

    Odoo stores individuals and organizations in the same res.partner table differentiated by company_type. Epicor separates these into Company (organizations, vendors, customers) and Person (contacts, employees) entities with a Contact relationship table linking Persons to Companies. We perform the split during migration scoping based on the company_type value and preserve the original Odoo partner ID for cross-reference. Migrations that skip this design step create orphaned Company records for individuals or duplicate Company entries for multi-contact organizations.

  • Product templates with variants restructure to flat Part records

    Odoo's product.template and product.product model means one product with four color variants is two database rows (one template, four variants). Epicor's Part model treats each manufactured or stocked item as one Part record. We split each Odoo variant into a separate Epicor Part and use PartAlt to preserve the template-to-variant grouping. For manufacturers using variants for ingredient sourcing in BoMs, this restructuring changes the BoM line item counts and requires Epicor PartRev recreation after the product split.

  • XML-RPC API has no batch endpoint; large extractions require PostgreSQL direct-read

    Odoo's External API exposes only standard xmlrpc execute_kw calls with no batch or bulk read endpoint. Manufacturing customers with 50,000+ parts, 10,000+ BoM lines, and 100,000+ stock.move records encounter server timeouts and 503 errors when extracting via XML-RPC at scale. We use direct PostgreSQL read from the Odoo database where the customer runs self-hosted Odoo with database access, bypassing the API bottleneck entirely. For Odoo.sh customers, we implement exponential backoff with jitter between batches of 500 records and resumable extraction checkpoints.

  • BOM routing operations map to PartOpr with workcenter translation

    Odoo's mrp.routing.workcenter (routing operations with cycle times, workcenter assignments, and step sequences) must translate to Epicor PartOpr records. Odoo workcenters do not map directly to Epicor Work Centers; we require a customer-provided workcenter mapping table during scoping. Multi-level Odoo BoMs (BoM referencing child BoM as a component) require recursive PartRev resolution in Epicor. We flag any还未 supported by Epicor (non-standard cost models, phantom BoMs, skip operations) during discovery so the customer can plan manual rebuild in Epicor's BOM Maintenance.

  • Country-specific fiscal localization does not migrate

    Odoo's accounting module embeds country-specific fiscal localization modules (fiscal positions, tax codes, Chart of Accounts templates, reporting requirements) that are tied to the Odoo installation country. These are not portable to Epicor because Epicor ships with its own country-specific Chart of Accounts and tax configuration. We extract Odoo fiscal positions and tax mapping rules as a written configuration inventory document for the customer's Epicor admin to reinstall in Epicor's Localization workbench. Posted journal entries and invoice records carry the Odoo tax structure and require remapping to Epicor tax codes during migration.

Migration approach

Six steps for a successful Odoo Enterprise to Epicor Prophet 21 data migration

  1. 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.

  2. 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.

  3. 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.

  4. 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.

  5. 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.

  6. 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

Context on both ends of the pair

Odoo Enterprise logo

Odoo Enterprise

Source

Strengths

  • Modular architecture means teams deploy CRM, Sales, Accounting, Inventory, and more from a single shared database without integration overhead.
  • Community Edition is free, open-source, and runs on any infrastructure, providing maximum flexibility for technical teams.
  • Unified client record (res.partner) used across all apps reduces data duplication and simplifies reporting across business functions.
  • Active third-party app ecosystem on the Odoo Apps store supplements core functionality for niche industry requirements.
  • XML-RPC External API is well-documented and supports all standard CRUD operations on every model, enabling reliable programmatic migration.

Weaknesses

  • Per-user, per-app pricing scales poorly: Enterprise costs grow linearly with headcount regardless of how lightly users touch the system.
  • Custom module development requires Python and Odoo ORM expertise; maintenance burden on custom code is high across version upgrades.
  • No official bulk/batch API endpoint: large-volume migrations must be chunked manually via the standard xmlrpc call loop, with timeout risk on large datasets.
  • Support quality is inconsistent; business-critical outages have been reported taking days to escalate to resolution.
  • Fiscal localization is deeply embedded in Odoo Accounting; switching countries or tax regimes requires significant reconfiguration rather than a simple settings change.
Epicor Prophet 21 logo

Epicor Prophet 21

Destination

Strengths

  • Purpose-built for wholesale distribution with industry-specific replenishment, kitting, and counter-sale workflows out of the box.
  • Multi-warehouse management with bin locations, cross-docking, and real-time inventory visibility across all warehouse locations.
  • Automated replenishment engine with demand-based and min-max planning reduces stockouts and overstock carrying costs.
  • AI-infused reporting via Epicor Prism provides Gen AI-driven insights into ERP data without requiring a BI team.
  • Strong customer retention at 90% and a 50-year track record in the distribution vertical provides long-term vendor stability.

Weaknesses

  • High total cost of ownership — per-user pricing of $150-200/month plus $10K-$500K implementation creates significant budget commitment for small and mid-market distributors.
  • Customization via SDK requires technical expertise and introduces upgrade risk when custom code conflicts with new P21 releases.
  • Report generation performance is a known pain point — multiple users report system freezes during large or complex report exports.
  • Third-party bolt-on reliance for functionality that competitors include natively increases integration complexity and total solution cost.
  • Limited public API documentation — developers building custom integrations report difficulty finding P21 API authentication methods and endpoint specifications.

Complexity grading

How hard is this migration?

Standard ERP migration. 2 of 8 objects need a mapping; the rest are 1:1.

B

Overall complexity

Standard migration

Derived from compatibility, mapping clarity, API constraints, and data volume across Odoo Enterprise and Epicor Prophet 21.

  • Object compatibility

    B

    2 of 8 objects need a mapping; the rest are 1:1.

  • 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

    Odoo Enterprise: Not publicly documented; timeouts observed on Odoo.sh at high request volumes.

  • Data volume sensitivity

    B

    Odoo Enterprise doesn't expose a bulk API — REST + parallelization used for high-volume runs.

Estimator

Estimate your Odoo Enterprise to Epicor Prophet 21 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 Odoo Enterprise to Epicor Prophet 21 data migrations

Answers to the questions buyers ask most during Odoo Enterprise to Epicor Prophet 21 migration scoping. Not seeing yours? Book a call.

Can't find your answer?

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 consultation

Smaller manufacturers with fewer than 10,000 parts, single-site inventory, and straightforward BoMs land in eight to twelve weeks for data migration scope. Multi-site deployments with complex multi-level Bill of Materials, work order history, lot/serial traceability across warehouses, and accounts payable/receivable reconciliation extend to sixteen to twenty-four weeks. The Odoo extraction phase alone takes one to three weeks depending on data volume and whether we use XML-RPC or PostgreSQL direct-read. Epicor REST API ingestion and parent-record resolution (PartNum in PartRev, Site in PartBin) adds sequencing time that simple CRM migrations do not have.

Adjacent paths

Related migrations to explore

Ready when you are

Move from Odoo Enterprise.
Land in Epicor Prophet 21, 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