CRM migration
Field-level mapping, validation, and rollback between erxes and Odoo CRM. We move data and schema; workflows are rebuilt natively in Odoo CRM.
erxes
Source
Odoo CRM
Destination
Compatibility
10 of 12
objects map 1:1 between erxes and Odoo CRM.
Complexity
BStandard
Timeline
3-6 weeks
Overview
Moving from erxes to Odoo CRM is a migration from a plugin-based open-source CRM to a modular open-source ERP whose CRM module is one component of a broader suite. erxes organizes data around Contacts, Companies, Deals in Pipelines, and Tasks organized into Teams and Cycles, all extracted via paginated GraphQL queries since no native bulk export UI exists. Odoo CRM uses a Partner record for both individuals and organizations, differentiated by Partner Type (contact vs company), with Opportunities linked to Partners and organized into stages within a single Pipeline. We resolve the erxes Company-to-Odoo Partner mapping and the erxes Contact-to-Odoo Partner mapping as separate import phases, using Odoo's partner deduplication on name and email to avoid creating duplicate records. Deal amounts, stage assignments, and custom fields migrate to Odoo Opportunity. Conversation history migrates to Odoo Mail Message records linked to the parent Partner. Workflows, automations, and Channels do not migrate as code; we deliver a written inventory of every active erxes automation and its Odoo Server Action or Automated Action equivalent for the customer's admin to rebuild.
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 erxes object lands in Odoo CRM, including any object-level transformations, lookup resolution, or schema-design dependencies.
Typical mapping — final map is confirmed during the sample migration step.
erxes
Contact
Odoo CRM
Partner (Partner Type = Individual)
1:1erxes Contact records map to Odoo Partner records with Partner Type set to Individual. The erxes primaryEmail becomes the Odoo email field; firstName and lastName split from erxes fullName on the first space. Phone and mobilePhone migrate to Odoo Partner phone and mobile fields. We run Odoo's partner deduplication on email before insert to avoid creating duplicate partners for records that appear in both the erxes Contact and Company objects. Custom field values from erxes Contacts migrate as Odoo custom fields on the res.partner model, with field type mapping (text to char, date to date, select to selection) verified against the Odoo field definition.
erxes
Company
Odoo CRM
Partner (Partner Type = Company)
1:1erxes Company records map to Odoo Partner records with Partner Type set to Company. The erxes domain field becomes the Odoo website field, and parentId on linked Contacts resolves to this Partner after Company import. We set Odoo's industry_id from erxes industry by matching against the Odoo res.partner.industry selection list. Companies without a domain or website are created as Odoo Partner records without the website field populated, and deduplication runs on company name to avoid duplicates from import retries.
erxes
Deal
Odoo CRM
Opportunity
1:1erxes Deals map to Odoo CRM Opportunity (crm.lead model). The erxes pipelineId and stageId translate to Odoo's team_id (Sales Team) and stage_id. Deal amount migrates to Odoo's expected_revenue and planned_revenue fields. The erxes createdAt timestamp preserves as Odoo's create_date. We resolve the partner_id on Odoo Opportunity by matching the erxes primaryCompanyId against the Partner records created in the Company import phase, falling back to matching by contact email if no Company link exists.
erxes
Pipeline
Odoo CRM
Team + Stage
lossyerxes Pipelines map to Odoo Sales Teams (crm.team model), and each erxes Pipeline Stage maps to an Odoo Stage within that Team. Stage names, probabilities, and order migrate. Odoo restricts Stages to a single sequence per team by default; if the erxes source uses multiple pipelines, we create a corresponding Odoo Sales Team per pipeline and map Deals accordingly. Stage probability percentages migrate to Odoo's probability field on crm.lead, rounded to nearest integer.
erxes
Task
Odoo CRM
Task (Project-based or Direct)
1:1erxes Tasks migrate to Odoo Task records. If the customer uses Odoo Project, tasks map to project.task; otherwise they map to crm.lead as internal notes or activities. Task title, description (as HTML), due date (date_deadline), and stage status migrate. Owner assignment resolves by matching erxes userId to Odoo res.users by email. erxes Cycle membership does not migrate as Odoo has no native Cycle equivalent; cycle-based task grouping is documented for manual reorganization in Odoo Project if the customer adopts it.
erxes
Conversation
Odoo CRM
Mail Message
1:1erxes multi-channel Conversations (email, SMS, chat, WhatsApp) migrate to Odoo Mail Message records linked to the parent Partner. We preserve message body, direction (inbound/outbound), channel type, and createdAt timestamp as mail.message create_date. Channel credentials such as WhatsApp API keys and email integration tokens do not migrate; we flag these for manual reconfiguration in Odoo because they are destination-system credentials. Message threading order depends on the erxes server timestamp, which we preserve during import to maintain chronological fidelity.
erxes
Custom Field
Odoo CRM
Custom Field (ir.model.fields)
lossyerxes custom fields defined on Contacts, Companies, Deals, and Tasks migrate to Odoo custom fields on the equivalent model (res.partner, crm.lead, project.task). We pre-create the Odoo field schema before data import, setting field type (char, text, date, selection, many2one) to match the erxes field type definition. erxes schema-less import behavior means field values may arrive as wrong types; we validate and cast values against the Odoo field type before insert, flagging any that fail cast.
erxes
User
Odoo CRM
User
1:1erxes Users map to Odoo res.users records. We resolve by email match during import. Any erxes User without a matching Odoo User goes to a reconciliation queue for the customer's admin to provision before Deal and Task import resumes. erxes role and permission configurations are destination-platform-specific and documented for manual rebuild in Odoo Access Rights settings.
erxes
Channel
Odoo CRM
Configuration (flag for manual rebuild)
1:1erxes Channels (email, SMS, chat, WhatsApp) define communication mediums and credentials connected to the platform. Channel API keys, webhook URLs, and third-party credentials do not migrate because they are source-system credentials that do not apply to Odoo. We deliver a written list of every active erxes Channel with its type, connected number or inbox, and a recommended Odoo equivalent configuration (Odoo Mail, a third-party WhatsApp integration app from the Odoo Apps store, or Odoo's SMS gateway) for the customer's admin to rebuild post-migration.
erxes
Automation Workflow
Odoo CRM
Configuration (flag for manual rebuild)
1:1erxes Automation Workflows define trigger-action sequences for customer journeys. We extract the workflow structure including triggers, conditions, and actions as a written inventory document. We do not migrate automations as code because erxes and Odoo use different rule engines. Each erxes automation is mapped to an Odoo Server Action or Automated Action equivalent (or a Planned Action on ir.cron) with trigger, condition, and action documented for the customer's Odoo admin to rebuild. Complex conditions referencing erxes object IDs are flagged individually because ID namespaces differ between systems.
erxes
Activity (engagement subtypes)
Odoo CRM
Mail Activity
1:1erxes engagement records with subtypes (call, email, meeting, note) map to Odoo Mail Activity records linked to the parent Partner or Opportunity. Activity type, subject, body, and due date migrate. Odoo Mail Activity supports types: call, meeting, email, upload_document, and task. We map erxes engagement subtype to the nearest Odoo activity_type_id. Owner assignment resolves via the User mapping by email.
erxes
Tag
Odoo CRM
Tag (crm.tag)
1:1erxes tags on Contacts, Companies, and Deals migrate to Odoo CRM Tags (crm.tag model). Tags stored as multi-checkbox custom properties in erxes migrate to individual crm.tag records with many2many relation to crm.lead. Tag names are preserved verbatim; tag colors and categories do not migrate as Odoo CRM Tags has no color field by default.
| erxes | Odoo CRM | Compatibility | |
|---|---|---|---|
| Contact | Partner (Partner Type = Individual)1:1 | Fully supported | |
| Company | Partner (Partner Type = Company)1:1 | Fully supported | |
| Deal | Opportunity1:1 | Fully supported | |
| Pipeline | Team + Stagelossy | Fully supported | |
| Task | Task (Project-based or Direct)1:1 | Fully supported | |
| Conversation | Mail Message1:1 | Fully supported | |
| Custom Field | Custom Field (ir.model.fields)lossy | Fully supported | |
| User | User1:1 | Fully supported | |
| Channel | Configuration (flag for manual rebuild)1:1 | Fully supported | |
| Automation Workflow | Configuration (flag for manual rebuild)1:1 | Fully supported | |
| Activity (engagement subtypes) | Mail Activity1:1 | Fully supported | |
| Tag | Tag (crm.tag)1: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.
erxes gotchas
No native bulk export in Community edition
Plugin activation state affects data visibility
Custom fields have no type enforcement during import
Conversation message ordering depends on server timestamps
Odoo CRM gotchas
Odoo.sh version gating blocks assisted migrations from trial
Enterprise modules fail to install on Community after database restore
Custom module view inheritance breaks between Odoo major versions
Custom fields risk losing their application context on Community
API access for Community is gated behind the Custom Plan
Pair-specific challenges
Migration approach
Discovery and plugin-state verification
We audit the source erxes installation across all active plugins, custom field definitions on Contacts, Companies, Deals, and Tasks, pipeline and stage count, user roster, active automation count, and conversation volume. We confirm all relevant erxes plugins are active during the pre-migration audit because deactivating a plugin before extraction renders its data inaccessible via the API. We pair this with an Odoo edition review: Odoo Online for hosted simplicity, Odoo.sh for git-based CI/CD deployments, or on-premise for strict data residency. The discovery output is a written migration scope document listing every object, field, pipeline, and automation in scope.
Data cleansing and schema pre-creation in Odoo
We run a data quality audit on the erxes export, identifying duplicate Contacts, blank required fields, malformed email addresses, and picklist values that will not map to Odoo selection lists. We cleanse records before migration rather than after because post-migration cleanup costs three to five times more in labor. In parallel, we pre-create the Odoo destination schema: custom fields on res.partner and crm.lead via ir.model.fields, CRM Tags via crm.tag, Sales Teams via crm.team, and Stage configurations. Schema is deployed to an Odoo Sandbox for validation before any production data loads.
Sandbox migration and reconciliation
We run a full migration into an Odoo Sandbox using production-equivalent data volume. The customer reconciles record counts (Partners from Contacts, Partners from Companies, Opportunities from Deals, Tasks, Mail Messages from Conversations), spot-checks 25-50 records against the erxes source, and signs off the schema and mapping before production migration begins. Any mapping corrections, field type cast failures, or deduplication rule adjustments happen in the Sandbox phase, not in production.
GraphQL extraction from erxes in dependency order
We extract erxes data via paginated GraphQL queries in record-dependency order: Companies first (to resolve companyId for Contact linking), then Contacts (with companyId reference), then Users (for owner mapping), then Deals (with pipelineId, stageId, and companyId resolved), then Tasks (with ownerId resolved), then Conversations (with contactId resolved). Large datasets (100,000+ records) are chunked with exponential backoff on API rate limit responses. Channel credentials, automation workflows, and plugin-specific data are extracted as metadata for the inventory document rather than as importable records.
Production migration in dependency order
We run production migration in record-dependency order: Partners from erxes Companies (with Partner Type = Company), Partners from erxes Contacts (with Partner Type = Individual, deduplicated on email), Sales Teams and Stages (from erxes Pipelines), Opportunities (with partner_id resolved from Company import and team_id resolved from Pipeline import), Tasks (with user_id resolved via User mapping), Mail Messages from Conversations (with res_id and model resolved to parent Partner), and Tags. Each phase emits a row-count reconciliation report before the next phase begins. We use Odoo's XML-RPC API with batch chunking and retry logic for transient errors.
Cutover, validation, and automation rebuild handoff
We freeze erxes writes during cutover, run a final delta migration of any records modified during the migration window, then enable Odoo CRM as the system of record. We deliver the automation and channel inventory document to the customer's admin team for rebuild in Odoo Studio or via custom Python modules. We support a one-week hypercare window where we resolve reconciliation issues raised by the customer's team. We do not rebuild erxes automations as Odoo Server Actions inside the migration scope; that is a separate engagement or an internal admin task.
Platform deep dives
erxes
Source
Strengths
Weaknesses
Odoo CRM
Destination
Strengths
Weaknesses
Complexity grading
Standard CRM 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 erxes and Odoo CRM.
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
erxes: Not publicly documented.
Data volume sensitivity
erxes 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 erxes to Odoo CRM migration scoping. Not seeing yours? Book a call.
Walk through your erxes to Odoo CRM migration with a real engineer — 30 minutes, free, written quote within 24 hours.
Book a free 30 minute consultationAdjacent paths
Other ways to leave erxes
Other ways to arrive at Odoo CRM
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.