CRM migration
Field-level mapping, validation, and rollback between OplaCRM and Odoo CRM. We move data and schema; workflows are rebuilt natively in Odoo CRM.
OplaCRM
Source
Odoo CRM
Destination
Compatibility
7 of 12
objects map 1:1 between OplaCRM and Odoo CRM.
Complexity
BStandard
Timeline
3-5 weeks
Overview
Moving from OplaCRM to Odoo CRM requires navigating two fundamentally different data architectures. OplaCRM maintains a three-tier model of Accounts, Contacts, and Opportunities with a composite healthscore per account and a UUID-based joint-opportunity linking pattern. Odoo CRM conflates leads and opportunities into crm.lead and handles companies and contacts as res.partner, a single partner model that serves both roles depending on context. We resolve these structural differences at migration time: we flatten the Account-Contact hierarchy into res.partner records with partner_ids linking where Odoo expects it, we split OplaCRM Opportunities into Odoo lead and opportunity states based on stage, we preserve the healthscore as a numeric custom field, and we surface Joint Opportunity UUIDs as a custom property so the team can rebuild the relationship manually or via Odoo Studio. We do not migrate workflows, automations, or the OplaCRM gamification layer; we deliver a written inventory of these for the customer's admin to reconstruct in Odoo.
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 OplaCRM 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.
OplaCRM
Account
Odoo CRM
res.partner (as company)
1:1OplaCRM Accounts map to Odoo CRM res.partner records with is_company = True. The Account name becomes partner display_name, and address fields map directly to Odoo's street, city, state, zip, and country fields. External ID from OplaCRM is preserved as an Odoo external ID so that Contact records can resolve the parent account at import time. We create res.partner records before any Contact import so the parent link is satisfied at insert time.
OplaCRM
Contact
Odoo CRM
res.partner (as individual)
1:1OplaCRM Contacts map to Odoo CRM res.partner records with is_company = False. Email is used as the dedupe key; if a res.partner with the same email already exists, we attach the Contact data to the existing record. The parent_id on the res.partner points to the Account-derived res.partner created in the prior phase. Role fields from OplaCRM migrate as a custom contact_type selection field if needed.
OplaCRM
Opportunity
Odoo CRM
crm.lead
lossyOplaCRM Opportunities map to Odoo CRM crm.lead records. We split by stage: OplaCRM opportunities with stage = CLOSE_WON migrate as Odoo crm.lead with type = opportunity and stage mapped to a won stage in the Odoo sales team pipeline. CLOSE_LOST stages map to lost. Active pipeline stages map as open leads with type = opportunity. The OplaCRM healthscore value migrates as a custom float field opla_healthscore__c on crm.lead for reporting continuity. The opportunities_joint_id UUID is preserved in a custom char field opla_joint_id__c for the team to resolve manually or via Odoo Studio.
OplaCRM
Opportunity Joint (Linked Opportunities)
Odoo CRM
crm.lead custom relationship
lossyOplaCRM links joint or co-selling opportunities using opportunities_joint_id, a UUID field that is not a standard linked-opportunity pattern. We preserve this UUID as a custom field opla_joint_id__c on crm.lead in Odoo. The team receives a pre-flight report listing every pair of opportunities that share the same joint UUID so they can decide whether to use Odoo Studio to create a custom many2many relationship, a project-linked-opportunity module from the Odoo AppStore, or handle joint deals manually in the opportunity name or description. We do not silently discard the relationship.
OplaCRM
Product
Odoo CRM
product.product
1:1OplaCRM Products map to Odoo product.product records. Product name, SKU (hs_sku equivalent), and list price migrate to name, default_code, and lst_price respectively. If OplaCRM stores pricing differently from Odoo's price book model, we flag this during pre-flight review and surface the discrepancy for the customer's admin to align before import.
OplaCRM
Invoice
Odoo CRM
account.move
1:1OplaCRM Invoices created via CreateOpportunityInvoiceDto map to Odoo account.move records with move_type = out_invoice. Invoice amount, date, and status migrate to amount_total, invoice_date, and payment_state respectively. Invoice numbering schemes between systems may require explicit remapping during pre-flight; we flag any numbering conflicts and propose a remapping strategy.
OplaCRM
Custom Fields
Odoo CRM
ir.model.fields
lossyOplaCRM CustomFieldValueDto key-value pairs migrate as Odoo ir.model.fields custom field definitions. We create each field in Odoo's technical settings with an appropriate field type (char, selection, text, float, date) before importing data. Any key that collides with an existing Odoo field name is prefixed with opla_ and surfaced in the pre-flight mapping table so the customer's admin can rename or merge before final cutover.
OplaCRM
Pipeline Stages
Odoo CRM
crm.stage
lossyOplaCRM stage names stored as plain string enums in sale_process_stage map to Odoo crm.stage by display label. CLOSE_WON and CLOSE_LOST are mapped explicitly to the terminal won and lost stages in the Odoo pipeline so closed deals land in the correct terminal state. Probability percentages from OplaCRM map to stage_sequence order in Odoo; the customer configures the visual pipeline Kanban stage order post-migration.
OplaCRM
Locked Records
Odoo CRM
crm.lead (restricted)
lossyOplaCRM locked records carry a boolean lock flag that prevents editing. In Odoo CRM, we set write_uid and create_uid restrictions on the crm.lead record so that only the admin or the original creating user can modify the record. If the customer does not have Odoo Studio or custom access rights configured, we create a custom boolean field opla_locked__c and surface it in the post-migration handoff so the admin can implement the appropriate access restriction.
OplaCRM
Tags / Labels
Odoo CRM
crm.tag
1:1OplaCRM tags stored as label arrays on records migrate to Odoo crm.tag records with tag names preserved. We split any comma-delimited tag strings into individual crm.tag entries and create crm.lead.tag.rel link records during import. The customer receives a tag consolidation report if duplicate or near-duplicate tags are detected.
OplaCRM
Attachments
Odoo CRM
ir.attachment
1:1OplaCRM attachments referenced by URL or file ID are downloaded and re-uploaded as Odoo ir.attachment records linked to the parent crm.lead or res.partner. Large binary attachments may require extended migration windows or a staged file transfer approach. We flag any attachments that exceed 25 MB during pre-flight so the customer can plan accordingly.
OplaCRM
User / Owner
Odoo CRM
res.users
1:1OplaCRM Users map to Odoo res.users records by email match. Any OplaCRM owner referenced on an Opportunity, Contact, or Account without a matching Odoo user goes to a reconciliation queue for the customer's admin to provision before record import resumes. Owner assignments migrate as user_id on crm.lead and responsible_id on res.partner.
| OplaCRM | Odoo CRM | Compatibility | |
|---|---|---|---|
| Account | res.partner (as company)1:1 | Fully supported | |
| Contact | res.partner (as individual)1:1 | Fully supported | |
| Opportunity | crm.leadlossy | Fully supported | |
| Opportunity Joint (Linked Opportunities) | crm.lead custom relationshiplossy | Fully supported | |
| Product | product.product1:1 | Fully supported | |
| Invoice | account.move1:1 | Fully supported | |
| Custom Fields | ir.model.fieldslossy | Mapping required | |
| Pipeline Stages | crm.stagelossy | Mapping required | |
| Locked Records | crm.lead (restricted)lossy | Mapping required | |
| Tags / Labels | crm.tag1:1 | Mapping required | |
| Attachments | ir.attachment1:1 | Mapping required | |
| User / Owner | res.users1: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.
OplaCRM gotchas
Opportunity Joint UUIDs require explicit resolution
Locked records need explicit permission remapping
Custom Fields stored as arbitrary key-value pairs may need normalization
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 scoping
We audit the source OplaCRM portal across all record types (Accounts, Contacts, Opportunities, Products, Invoices), custom field inventory, locked-record count, active pipeline stage names, and joint opportunity volume. We pair this with an Odoo CRM environment review: active apps, existing res.partner records, crm.lead stage configuration, and installed modules. The discovery output is a written migration scope document that specifies the Account-Contact flattening strategy, the lead-opportunity split rule, the joint-UUID handling approach, and the locked-record remediation plan. We also identify any Odoo apps that need activation before migration (CRM, Sales, Invoicing, Inventory) to ensure the destination environment is properly licensed.
Odoo schema design and field pre-creation
We design the destination schema in Odoo CRM before any data is written. This includes creating all custom ir.model.fields for OplaCRM custom field key-value pairs, configuring crm.lead stages to match OplaCRM pipeline stage names, defining the res.partner hierarchy with parent_id links for Account-Contact relationships, and creating the opla_joint_id__c and opla_locked__c custom fields. Schema changes are validated in an Odoo sandbox environment before production migration begins. We also configure the lead-opportunity split rule based on the customer's stage matrix so that closed-won and active pipeline records land as opportunities rather than leads.
Sandbox migration and reconciliation
We run a full migration into an Odoo test environment using a representative data volume snapshot. The customer's Odoo administrator reconciles record counts (Accounts in, res.partner in, Contacts in, Opportunities in), spot-checks 25-50 random records against the OplaCRM source, and validates that stage mapping, healthscore preservation, and joint-UUID assignment are correct. Any mapping corrections, field type adjustments, or stage name remapping happen in this phase. We do not proceed to production migration until the sandbox reconciliation is signed off.
Owner reconciliation and user provisioning
We extract every distinct OplaCRM owner referenced on Accounts, Contacts, Opportunities, and Invoices and match by email against the Odoo destination res.users table. Owners without a matching Odoo user go to a reconciliation queue. The customer's Odoo administrator provisions any missing users and assigns appropriate access rights (Sales / Administrator) before migration resumes. Owner assignments are resolved at this stage so that user_id on crm.lead and responsible_id on res.partner can be populated during data import.
Production migration in dependency order
We run production migration in record-dependency order: res.users (validated), res.partner as companies (from OplaCRM Accounts), res.partner as contacts (from OplaCRM Contacts with parent_id resolved to Account partner), crm.lead stages (pipeline configuration), crm.lead as opportunities (from OplaCRM Opportunities with stage mapping, healthscore, and joint UUID preserved), product.product (from OplaCRM Products), account.move (from OplaCRM Invoices), crm.tag (from OplaCRM labels), ir.attachment (from OplaCRM file references), and custom fields (last, after all parent record IDs are resolved). Each phase emits a row-count reconciliation report before the next phase begins.
Cutover, validation, and automation rebuild handoff
We freeze writes to OplaCRM during the cutover window, 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 joint-opportunity UUID report, the locked-record list with opla_locked__c status, and the automation and workflow inventory for the customer's Odoo administrator to rebuild. We support a one-week hypercare window where we resolve any reconciliation issues raised by the customer's sales team. We do not rebuild OplaCRM workflows, gamification layers, or sequences inside the migration scope; those are documented separately for the customer's admin or an Odoo partner to reconstruct.
Platform deep dives
OplaCRM
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 OplaCRM 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
OplaCRM: Not publicly documented.
Data volume sensitivity
OplaCRM 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 OplaCRM to Odoo CRM migration scoping. Not seeing yours? Book a call.
Walk through your OplaCRM 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 OplaCRM
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.