ERP migration
Field-level mapping, validation, and rollback between Oracle JD Edwards EnterpriseOne and Odoo ERP. We move data and schema; workflows are rebuilt natively in Odoo ERP.
Oracle JD Edwards EnterpriseOne
Source
Odoo ERP
Destination
Compatibility
8 of 12
objects map 1:1 between Oracle JD Edwards EnterpriseOne and Odoo ERP.
Complexity
BStandard
Timeline
6-9 weeks
Overview
Moving from Oracle JD Edwards EnterpriseOne to Odoo ERP is a cross-ERP migration from a table-driven, on-premises system to a modular open-source ERP with a REST-oriented API. JDE stores business records across a well-documented but complex F-prefix table hierarchy (F0101 for Address Book, F0901 for General Ledger, F4211 for Sales Orders) where row-level denormalization is common, whereas Odoo uses a normalized relational model with distinct partner, product, sale order, and account.move tables connected by integer foreign keys. We connect directly to the JDE Oracle or SQL Server database, extract business data using targeted SELECT statements scoped to licensed modules, transform records to match Odoo's field types and naming conventions, and load through Odoo's XML-RPC API with batch chunking and parent-lookup resolution. Manufacturing work orders, Advanced Pricing schedules, and media object attachments require dedicated extraction and transformation passes because they have no single Odoo equivalent. We do not migrate JDE workflows, UBEs, or UDOs as deployable artifacts; we deliver a written inventory of these objects for the customer's Odoo partner to rebuild in Studio or as custom modules.
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 Oracle JD Edwards EnterpriseOne 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.
Oracle JD Edwards EnterpriseOne
Address Book (F0101, F0111, F0116)
Odoo ERP
res.partner
1:1JDE's Address Book is the master entity table for customers, suppliers, employees, and prospects, stored across F0101 (header), F0111 (contact info), and F0116 (phone numbers). We extract by address type code (AT1 = customer, AT2 = supplier, E = employee) to set Odoo's partner_type field and is_company flag. Parent-child relationships in F0101 (AN8 and ABO) map to Odoo's parent_id on res.partner. Tax IDs and category codes in F0101 map to Odoo's vat field and category_id many2many. Address records with no corresponding AN8 are held for reconciliation against employee and prospect records.
Oracle JD Edwards EnterpriseOne
General Ledger Account Master (F0901)
Odoo ERP
account.account
1:1JDE GL account structures use business unit, object account, and subsidiary segments concatenated into a single account code (BU.OBJ.SUB). We extract the full F0901 chart of accounts, parse the segment structure, and map to Odoo's account.account with the correct account_type (asset, liability, equity, revenue, expense). Account balances from F0902 migrate to Odoo's account.move and account.move.line records. Multi-currency ledgers in JDE map to Odoo's account.account with foreign_currency_revaluation enabled.
Oracle JD Edwards EnterpriseOne
Accounts Payable (F0411, F0414)
Odoo ERP
account.move (type = 'in_invoice'), account.move.line
1:1JDE stores open AP invoices in F0411 with payment terms in F0414. Each invoice line is a separate F0411 row with G/L distribution. We reconstruct invoices as Odoo account.move records of type in_invoice, with line items linked to the vendor partner (res.partner), the AP account, and the corresponding GL account from F0901. Outstanding invoice balances carry forward as Odoo lines in draft state until the customer's AP team reconciles and posts.
Oracle JD Edwards EnterpriseOne
Accounts Receivable (F0311, F03B11)
Odoo ERP
account.move (type = 'out_invoice'), account.move.line
1:1Open AR invoices in F0311 and F03B11 map to Odoo account.move records of type out_invoice. JDE's invoice number and batch number become Odoo's ref and invoice_origin fields. Credit memos (document type DM) map to out_refund. Open receivable amounts are preserved as line-level balance values, and Odoo's reconciled flag is set false until the customer's AR team posts payments against the migrated invoices.
Oracle JD Edwards EnterpriseOne
Item Master (F4101) and Branch Plant (F4102)
Odoo ERP
product.template, stock.warehouse
1:manyJDE item master records in F4101 carry description, unit of measure, cost, and stocking type. Branch plant data in F4102 carries on-hand quantities and location assignments per warehouse. We split F4101 into Odoo's product.template (name, default_code, list_price, standard_price) and product.product variants if lot/serial tracking is active. Each F4102 branch plant becomes an Odoo stock.warehouse with its own location hierarchy. Category codes in F4101 map to Odoo's categ_id and product_tags.
Oracle JD Edwards EnterpriseOne
Sales Order Header (F4211)
Odoo ERP
sale.order
1:1JDE sales order headers live in F4211 with pricing, branch plant, and order date embedded at the line level. We extract order headers separately, map order status codes (970 = cancelled, 999 = held) to Odoo's state values (cancel, sale_order), and preserve the original JDE order number as the Odoo name field. Customer and branch plant references resolve to the migrated res.partner and stock.warehouse lookups before insertion.
Oracle JD Edwards EnterpriseOne
Sales Order Lines (F42119)
Odoo ERP
sale.order.line
1:1JDE order lines in F42119 are distinct rows with pricing, taxes, branch plant, and schedule dates embedded per line. We extract each F42119 row, resolve the product.product reference from F4101 mapping, map the F4211 header key (DOCO, KCOO, DCTO) as the parent sale.order, and create Odoo sale.order.line with qty_delivered and qty_invoiced preserved for open orders. Lines attached to cancelled orders are excluded from migration.
Oracle JD Edwards EnterpriseOne
Purchase Order (F4311)
Odoo ERP
purchase.order, purchase.order.line
1:1JDE purchase orders use F4311 with a complex row structure where receipt and invoicing lines intermingle. We extract PO headers and lines separately, map line-level branch plant and G/L class to the corresponding Odoo stock.location and account.account. Open POs migrate as purchase.order records in state 'purchase' with lines in purchase.order.line. Closed or received POs migrate in state 'done'.
Oracle JD Edwards EnterpriseOne
Work Order (F4801, F3112, F3003)
Odoo ERP
mrp.production, mrp.bom, mrp.routing.workcenter
1:manyJDE manufacturing work orders store routing operations in F3112 and BOM components in F3003 as separate tables linked to the F4801 header. We extract the complete work order assembly and split into Odoo's mrp.production (the work order), mrp.bom (the bill of materials from F3003), and mrp.routing.workcenter (operations from F3112). BOM type codes in JDE (M = manufacturing, D = kit) map to Odoo's type field on mrp.bom. Work order status codes (91 = released, 97 = closed) map to Odoo's state on mrp.production.
Oracle JD Edwards EnterpriseOne
Advanced Pricing (F4072)
Odoo ERP
product.pricelist, product.pricelist.item
1:manyJDE pricing schedules in F4072 store break quantities, adjustment types, effective dates, and commodity table references. Each F4072 schedule maps to an Odoo product.pricelist with a corresponding product.pricelist.item row per pricing rule. Volume breaks, effective date ranges, and customer-specific pricing all become Odoo pricelist rules with different applied_on and compute_price settings. Complex formula-based pricing in JDE is documented for Odoo partner configuration during the migration acceptance phase.
Oracle JD Edwards EnterpriseOne
Media Objects (F00165)
Odoo ERP
ir.attachment
1:1JDE media objects including attachments, images, and embedded documents are stored in the F00165 table and related filesystem paths. Oracle recommends running the R98MODAT utility to load all media objects into F00165 before export. We invoke R98MODAT as a pre-export step, extract media objects with their F00165 keys, and map each to Odoo's ir.attachment with res_model and res_id pointing to the migrated parent record (res.partner, product.product, sale.order) based on the object type stored in F00165's subject field.
Oracle JD Edwards EnterpriseOne
User Defined Objects (UDOs)
Odoo ERP
Custom Odoo modules
lossyJDE UDOs — custom UBEs, custom tables, and extended business objects tracked in the Object Management Workbench — have no direct Odoo equivalent. UDOs reserved to a specific JDE project are reassigned to the user's default project during export; we document all UDO project assignments, data schemas, and field definitions in a written inventory that the customer's Odoo partner uses to rebuild equivalent custom modules in Python. We do not write Odoo custom module code as part of the standard migration scope.
| Oracle JD Edwards EnterpriseOne | Odoo ERP | Compatibility | |
|---|---|---|---|
| Address Book (F0101, F0111, F0116) | res.partner1:1 | Fully supported | |
| General Ledger Account Master (F0901) | account.account1:1 | Fully supported | |
| Accounts Payable (F0411, F0414) | account.move (type = 'in_invoice'), account.move.line1:1 | Fully supported | |
| Accounts Receivable (F0311, F03B11) | account.move (type = 'out_invoice'), account.move.line1:1 | Fully supported | |
| Item Master (F4101) and Branch Plant (F4102) | product.template, stock.warehouse1:many | Fully supported | |
| Sales Order Header (F4211) | sale.order1:1 | Fully supported | |
| Sales Order Lines (F42119) | sale.order.line1:1 | Fully supported | |
| Purchase Order (F4311) | purchase.order, purchase.order.line1:1 | Fully supported | |
| Work Order (F4801, F3112, F3003) | mrp.production, mrp.bom, mrp.routing.workcenter1:many | Fully supported | |
| Advanced Pricing (F4072) | product.pricelist, product.pricelist.item1:many | Fully supported | |
| Media Objects (F00165) | ir.attachment1:1 | Mapping required | |
| User Defined Objects (UDOs) | Custom Odoo moduleslossy | Mapping required |
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.
Oracle JD Edwards EnterpriseOne gotchas
JDE-to-Cloud version parity is mandatory
Media objects must be pre-loaded before export
User Defined Objects lose their project reservation
AIS REST API requires token-based authentication on v2 endpoints
Workflow thresholds silently suppress notifications
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 module scoping
We audit the source JDE environment using the Oracle Cloud Migration Utility scoping output and direct database queries against the Oracle or SQL Server backend. We identify which JDE modules are licensed and active (Financial Management, Supply Chain Management, Manufacturing), the Tools and Applications release version (Tools Release 9.2.x with Applications 9.1 or later is the minimum for utility-based export), the database backend (Oracle or SQL Server), and the count of records per table. We also inventory UDOs, custom reports, and pricing schedules during discovery. The discovery output is a written migration scope with record counts per object, a schema map linking JDE tables to Odoo models, and a pricing schedule recommendation based on Odoo plan selection.
R98MODAT and pre-export preparation
We invoke the R98MODAT utility on the JDE deployment server to load all filesystem-resident media objects into the F00165 database table before any data extraction. We also run a full package build to populate the JDE repository tables, check version parity against the Odoo target schema, and validate that the F0005 data dictionary field types are recorded for every custom field used in the migration scope. This step is mandatory on Tools Release 9.2.1 and later; skipping it results in silent exclusion of media objects from the dump.
Data extraction from JDE tables
We connect directly to the JDE Oracle or SQL Server database and run targeted SELECT statements scoped to the licensed modules and active business units. We extract in dependency order: Address Book (F0101, F0111, F0116) first to resolve entity keys, then GL account master (F0901) and balances (F0902), then inventory items (F4101, F4102), then transactional tables (F4211, F42119, F4311, F0311, F0411), then work order and BOM tables (F4801, F3112, F3003) last. We use database-level row sampling to validate record counts against JDE's P0036G inquiry screen before full extraction, and we capture the JDE AN8, DOCO, and other business keys as external identifiers for lookup resolution in Odoo.
Schema design and Odoo environment preparation
We provision the destination Odoo environment and configure the active apps matching the migration scope (contacts, accounting, inventory, purchase, sale, mrp). We create the Odoo account chart with the same root account structure as JDE's GL, configure warehouse locations matching JDE branch plants, set up Odoo product categories mapped to JDE category codes, and configure sale and purchase price lists from JDE's F4072 pricing schedules. We disable Odoo's default accounting template sequence conflicts before loading data so that account.move names do not collide with migrated GL entries.
Data transformation and Odoo XML-RPC load
We transform extracted JDE records into Odoo's XML-RPC-compatible JSON format, resolving all foreign key lookups (partner_id, product_id, account_id, warehouse_id) before insertion. We load in dependency order through Odoo's XML-RPC API: res.partner first, then product.template and product.product, then account.account, then stock.warehouse and stock.location, then sale.order and purchase.order with their lines, then mrp.production and mrp.bom, then account.move records for GL, AP, and AR. We use batch chunking with a target of 500 records per API call and exponential backoff on rate-limit responses. Media objects from F00165 are inserted as ir.attachment records with the correct res_model and res_id references resolved from the parent record mapping.
Sandbox reconciliation and UDO handoff
We run a full migration into a test Odoo database and perform record-count reconciliation against the source JDE extract output for every object. The customer's finance and operations leads spot-check 30-50 records across GL balances, open AR/AP invoices, and open sales orders against the JDE source data. We deliver the UDO and custom UBE inventory document listing every JDE custom object, its schema, and its Odoo equivalent rebuild recommendation. Any mapping corrections identified during reconciliation are applied to the production migration script before cutover.
Production cutover and go-live support
We freeze JDE writes during the cutover window, run a final delta extraction for any records modified during migration testing, then load into the production Odoo environment. We perform a post-load reconciliation comparing total debit and credit balances against the JDE GL to confirm financial integrity, verify open sales order and purchase order counts, and confirm inventory on-hand quantities per warehouse. We provide a one-week hypercare window for reconciliation issues raised by the customer's team. We do not rebuild JDE workflows or UBEs in Odoo; the UDO handoff document is delivered at cutover for the customer's Odoo partner to action as a separate engagement.
Platform deep dives
Oracle JD Edwards EnterpriseOne
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 Oracle JD Edwards EnterpriseOne 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
Oracle JD Edwards EnterpriseOne: Not publicly documented by Oracle for the AIS Server REST API.
Data volume sensitivity
Oracle JD Edwards EnterpriseOne 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 Oracle JD Edwards EnterpriseOne to Odoo ERP migration scoping. Not seeing yours? Book a call.
Walk through your Oracle JD Edwards EnterpriseOne 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 Oracle JD Edwards EnterpriseOne
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.