CRM migration
Field-level mapping, validation, and rollback between Oncourse CRM and Odoo CRM. We move data and schema; workflows are rebuilt natively in Odoo CRM.
Oncourse CRM
Source
Odoo CRM
Destination
Compatibility
7 of 12
objects map 1:1 between Oncourse CRM and Odoo CRM.
Complexity
BStandard
Timeline
2-4 weeks
Overview
Oncourse CRM uses a flat contact model where organization names are stored as a contact property rather than a separate account object. Odoo CRM expects Contacts to be linked to Partners (res.partner records) that serve as the Account equivalent. We extract the organization value from each Oncourse Contact, create the Odoo Partner record first, then link the Contact to it during import. Oncourse stores engagement history as free-text notes rather than structured activity records, so we transform these into Odoo chatter entries and mail.message records attached to the relevant Lead, Contact, or Opportunity. Pipeline stages migrate as Odoo stage records within the crm.stage model, preserving the stage sequence and probability values configured in Oncourse. Oncourse has no public attachment export API, so file attachments cannot be migrated in an automated run and require a manual backup recommendation. Odoo is an integrated ERP suite; Automations and CRM Workflow configurations in Oncourse do not migrate as code. We deliver a written inventory of active automations for the customer's Odoo admin to rebuild in Odoo's Action and Automated Action frameworks post-migration.
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 Oncourse CRM 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.
Oncourse CRM
Lead
Odoo CRM
Lead (crm.lead)
1:1Oncourse Leads migrate directly to Odoo crm.lead records. The lead source and status properties from Oncourse map to Odoo's source_id (crm.lost_reason reference) and stage_id fields. We preserve the Oncourse lead score if exposed via the export as a custom float field on the Odoo lead. Lead priority maps to crm.lead priority selection.
Oncourse CRM
Contact
Odoo CRM
Contact (res.partner)
1:1Oncourse Contact records migrate to Odoo res.partner records. The partner_id field in Odoo CRM Links to a separate Partner record for organization data; we extract the organization value from Oncourse Contacts, create the Odoo Partner first, then link the Contact res.partner record via parent_id (for personal vs company contacts). Name, email, phone, and address fields map directly without transformation.
Oncourse CRM
Companies/Accounts
Odoo CRM
Partner (res.partner)
lossyOncourse may associate contacts with organization names stored as a Contact property rather than a distinct Account object. We extract the distinct organization values from all Oncourse Contacts, create Odoo res.partner records with partner_type set to company, then update the Contact-level partner records to reference the parent company via parent_id. If Oncourse has no separate Companies object, this N:1 merge creates the account hierarchy in Odoo that the flat Oncourse model lacks.
Oncourse CRM
Deal
Odoo CRM
Opportunity (crm.lead)
1:1Oncourse Deals migrate to Odoo crm.lead records in the Opportunity stage. Deal name, value, and stage map to Odoo's name, expected_revenue (stored as float), and stage_id. Owner assignment from Oncourse maps to Odoo user_id via email-match resolution against the Odoo res.users table. Closed-Lost and Closed-Won states from Oncourse stage names map to Odoo lost and won stage values.
Oncourse CRM
Pipeline Stages
Odoo CRM
Stage (crm.stage)
lossyOncourse pipeline stage names are extracted during scoping and mapped to Odoo crm.stage records within the relevant Odoo CRM team sequence. We create any missing stages in Odoo before Deal migration so that stage_id references are valid at import time. Stage probability values from Oncourse migrate to Odoo's stage probability field.
Oncourse CRM
Pipeline
Odoo CRM
Sales Team (crm.team)
lossyIf Oncourse has multiple pipelines per account, we map each Oncourse pipeline to a separate Odoo Sales Team (crm.team) with its own stage sequence. Odoo Sales Teams provide team-level pipeline visibility and are available from Odoo 17 Community onward.
Oncourse CRM
Task
Odoo CRM
Task (project.task)
1:1Oncourse Tasks linked to Deals migrate to Odoo project.task records. We create a project.task record per Oncourse task, set the crm.lead reference in the related_id or project_id field, and preserve status, priority, and due date. Tasks not linked to a Deal become standalone project.task records under a default migration project in Odoo.
Oncourse CRM
Engagement: Note
Odoo CRM
Chatter Post (mail.message)
1:1Oncourse activity history stored as free-text notes on Deals migrates to Odoo mail.message records (chatter entries) attached to the relevant crm.lead. We parse the note body, create an Odoo mail.message with message_type = comment, and attach it to the corresponding Odoo Lead or Opportunity record. Note creation timestamp becomes mail.message's date field. This reconstructs the activity timeline in Odoo's native chatter model.
Oncourse CRM
Custom Fields
Odoo CRM
Custom Fields (ir.model.fields)
lossyCustom fields on Oncourse Leads, Contacts, and Deals are mapped to Odoo custom ir.model.fields on the corresponding model (crm.lead or res.partner). Field data types from the onCourse DSL export (text, number, date, currency) map to the closest Odoo field type (char, float, datetime, monetary). We pre-create the custom fields in Odoo via the Settings > Technical > Custom Fields interface before data import so that target columns exist at migration time.
Oncourse CRM
Owner
Odoo CRM
User (res.users)
1:1Oncourse Owner references on Deals and Tasks resolve to Odoo res.users records by email match. Any Oncourse Owner without a matching Odoo User is placed in a reconciliation queue; the customer's Odoo admin provisions the missing user before the relevant records import. This step gates Deal and Task imports because user_id is a required field on crm.lead in Odoo.
Oncourse CRM
Lead Source
Odoo CRM
Source (crm.tag or custom char field)
lossyOncourse Lead Source values migrate to Odoo crm.tag records if the customer uses tag-based lead source tracking, or to a custom selection field on crm.lead. We do not create new Odoo crm.lost_reason records for lead sources; we recommend a custom char or selection field to avoid conflating lead source with lost-reason tracking.
Oncourse CRM
Attachments
Odoo CRM
ir.attachment
1:1Oncourse CRM does not expose a public file attachment export via its standard import/export tooling. We cannot guarantee attachment migration in automated runs. We recommend a manual backup of the document storage in Oncourse before migration cutover. If the customer provides a manual export of attachments, we map them to Odoo ir.attachment records with res.model set to crm.lead or res.partner and res.id set to the migrated record ID.
| Oncourse CRM | Odoo CRM | Compatibility | |
|---|---|---|---|
| Lead | Lead (crm.lead)1:1 | Fully supported | |
| Contact | Contact (res.partner)1:1 | Fully supported | |
| Companies/Accounts | Partner (res.partner)lossy | Mapping required | |
| Deal | Opportunity (crm.lead)1:1 | Fully supported | |
| Pipeline Stages | Stage (crm.stage)lossy | Mapping required | |
| Pipeline | Sales Team (crm.team)lossy | Fully supported | |
| Task | Task (project.task)1:1 | Fully supported | |
| Engagement: Note | Chatter Post (mail.message)1:1 | Fully supported | |
| Custom Fields | Custom Fields (ir.model.fields)lossy | Mapping required | |
| Owner | User (res.users)1:1 | Fully supported | |
| Lead Source | Source (crm.tag or custom char field)lossy | Fully supported | |
| Attachments | ir.attachment1:1 | Not 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.
Oncourse CRM gotchas
Attachments are not exportable via the standard import/export tooling
Activity history lives in notes, not structured records
Pipeline stages are tenant-defined free text
Voice and SMS allowances cap at 400 each on Standard
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
Oncourse data extraction and scoping
We export Leads, Contacts, Deals, Tasks, and custom fields from Oncourse CRM via the platform's export tooling. We audit the flat contact model to identify which Contacts carry organization values, how many distinct organizations exist, and whether any organization values map to a separate Companies object in Oncourse. We also identify the active pipeline stage names and note-count per Deal to estimate activity reconstruction work. The scoping output is a written migration scope document covering record counts, object dependencies, and the organization-extraction strategy.
Odoo environment preparation
We set up the Odoo CRM pipeline in the destination instance: creating the required crm.stage records, configuring the CRM Sales Team (crm.team), and creating any custom fields on crm.lead and res.partner to receive the migrated data. If the destination Odoo instance already has existing Partner records (from other Odoo apps), we run a dedupe check against the incoming Contact list using email as the match key. We also provision the migration service user with write access to crm.lead, res.partner, project.task, and mail.message.
Organization extraction and Partner pre-creation
We extract distinct organization names from Oncourse Contact records, create Odoo res.partner records of type company for each distinct organization, and store the mapping between the Oncourse organization value and the new Odoo Partner ID. This mapping is required before Contact-level records can import because Odoo requires parent_id references on Contact-type Partner records to be valid at insert time.
Lead and Contact migration with parent resolution
We migrate Oncourse Leads to Odoo crm.lead records first. We then migrate Oncourse Contacts to res.partner records of type contact, applying the organization-to-Partner mapping as the parent_id on each Contact record. Custom fields on both Leads and Contacts are mapped to the pre-created custom fields in Odoo. Email is the dedupe key; any Odoo Partner matching the incoming email receives an update rather than a duplicate insert.
Deal and Opportunity migration with stage mapping
We migrate Oncourse Deals to Odoo crm.lead records in the Opportunity stage, applying the stage mapping (Oncourse stage name to Odoo crm.stage ID) computed during scoping. Owner assignment resolves by email match against Odoo res.users. Deal value migrates to expected_revenue, and the closed-won and closed-lost stage names in Oncourse map to the corresponding Odoo won and lost stage values.
Activity note reconstruction and Task migration
We transform Oncourse Deal notes into Odoo mail.message records (chatter posts) attached to the corresponding crm.lead. Each note becomes a comment-type message with the original note timestamp preserved. Oncourse Tasks linked to Deals migrate as project.task records with the crm.lead referenced in the task's related_id. Activity note reconstruction and Task migration run as a final pass after the core CRM record migration is validated.
Cutover, validation, and automation inventory delivery
We freeze Oncourse CRM 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 a record-count reconciliation report (Contacts in, Leads in, Partners in, Opportunities in, tasks migrated, chatter posts created) for the customer's sign-off. We also deliver the written Oncourse automation inventory document for the customer's Odoo admin to rebuild post-migration. We do not rebuild automations or configure Odoo Action Rules as part of the migration scope.
Platform deep dives
Oncourse CRM
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 Oncourse CRM 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
Oncourse CRM: Not publicly documented.
Data volume sensitivity
Oncourse CRM 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 Oncourse CRM to Odoo CRM migration scoping. Not seeing yours? Book a call.
Walk through your Oncourse CRM 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 Oncourse CRM
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.