CRM migration
Field-level mapping, validation, and rollback between MARS and Odoo CRM. We move data and schema; workflows are rebuilt natively in Odoo CRM.
MARS
Source
Odoo CRM
Destination
Compatibility
10 of 14
objects map 1:1 between MARS and Odoo CRM.
Complexity
CModerate
Timeline
3-5 weeks
Overview
Moving from MARS to Odoo CRM is a data restructuring migration, not a record copy. MARS stores Contacts, Companies, and Deals as separate primary objects; Odoo CRM uses the res.partner model for both individual contacts and organizations, with opportunities linked as crm.lead records. We resolve the MARS Company-to-res.partner mapping during scoping, splitting company-level data onto a commercial partner record and contact-level data onto a separate contact partner record, with proper address inheritance. Activity history in MARS migrates to Odoo's mail.message and crm.activity models via XML-RPC batch insertion with parent-record resolution. Workflows, email templates, and reporting configurations do not migrate; we deliver a written inventory of these for the customer to rebuild in Odoo Studio or through custom development.
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 MARS 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.
MARS
Contact
Odoo CRM
res.partner (individual)
1:1MARS Contact records map to Odoo res.partner with partner_type set to 'contact'. The MARS first_name and last_name fields concatenate to the res.partner name field. Email maps to email, phone to phone, and mobile to mobile. Street, city, state, zip, country from MARS address fields map to street, city, state_id (resolved from country/state table), zip, and country_id. We create the res.partner record first so that it is available as a parent_id for any MARS Contact records that share the same company.
MARS
Company
Odoo CRM
res.partner (company)
1:1MARS Company records map to Odoo res.partner with partner_type set to 'company' and is_company set to True. The company name becomes res.partner name. Website, industry, employee_count, and annual_revenue map to website, industry_id, employee_count, and revenue fields respectively. We use the MARS company domain to populate website without the http prefix. The commercial partner (contact of the company contact) is created for company-level contacts that exist in MARS as Company-linked individuals.
MARS
Deal
Odoo CRM
crm.lead (opportunity)
1:1MARS Deal records map to Odoo crm.lead with type set to 'opportunity'. The MARS deal name maps to name, expected_close_date to date_deadline, amount to planned_revenue, and probability to probability (with stage-based defaults overridden if MARS stores explicit probability). partner_id (the commercial partner lookup) is resolved from the MARS deal's linked company or contact via email domain match against res.partner. user_id maps to the Odoo res.users owner resolved by email.
MARS
Deal Stage
Odoo CRM
crm.stage
lossyEach MARS pipeline stage becomes an Odoo crm.stage record within the relevant crm.team's stage pool. Stage sequence order and name migrate directly. Probability percentages migrate to the probability field on each stage. If MARS stores won/lost as stage properties, these map to fold (archived won) and stage_type (won/lost). We configure stage before opportunity migration so that stage_id lookups resolve during import.
MARS
Pipeline
Odoo CRM
crm.team + crm.stage pool
lossyMARS deal pipelines map to Odoo crm.team records (one per pipeline). Each crm.team gets its own stage pool via team_use = 'multi' in the crm.team configuration. Stage assignments in MARS determine which crm.team a crm.lead belongs to via the team_id field. This mapping requires crm.team to be created before opportunities are imported.
MARS
Owner
Odoo CRM
res.users
1:1MARS Owner records are resolved by email match against Odoo res.users. The MARS owner_id on each Contact, Company, and Deal record maps to the user_id or user_ids field in Odoo on the corresponding model. Any MARS Owner without a matching Odoo res.users is placed in a reconciliation queue for the customer's admin to provision the User before record import resumes.
MARS
Activity: Email
Odoo CRM
mail.message
1:1MARS email engagements map to Odoo mail.message records with message_type = 'email'. The email subject maps to subject, body to body (HTML preserved), and date to date. The mail.message record is linked to its parent res.partner via res_id and model = 'res.partner'. We batch insert via XML-RPC in chunks of 100 to respect Odoo's request size limits.
MARS
Activity: Call
Odoo CRM
crm.activity
1:1MARS call engagements map to Odoo crm.activity records with activity_type_id referencing the phone call activity type. Call duration, disposition, and notes map to custom fields on crm.activity. The activity is linked to the parent res.partner (contact) via res_id and model. Activity date preserves the original MARS timestamp for timeline ordering.
MARS
Activity: Meeting
Odoo CRM
calendar.event
1:1MARS meeting engagements map to Odoo calendar.event records. Start datetime and end datetime migrate to start and stop. Location maps to location. Attendees are linked via calendar.attendee records pointing to the res.partner invitees. Meeting notes map to description. We create calendar.event records via XML-RPC after res.partner records are fully loaded.
MARS
Activity: Task
Odoo CRM
project.task or crm.activity
lossyMARS task engagements map to Odoo project.task if the customer requires project management capabilities, or to crm.activity if tasks are scoped to CRM activity tracking. Task title, description, due date, priority, and completion status migrate directly. Assignment resolves to res.users via email match. The customer selects the target model during scoping.
MARS
Tag
Odoo CRM
crm.tag + crm.lead.tag.rel
1:1MARS tags on Deals map to Odoo crm.tag records. The tag-to-record association migrates via crm.lead.tag.rel (many-to-many). Tags stored on Contacts map via res.partner.category (which is a generic tag model in Odoo used across multiple objects). Tag names preserve exactly as stored in MARS for consistency with existing reporting.
MARS
Custom Field
Odoo CRM
ir.model.fields
lossyMARS custom fields on Contact, Company, and Deal objects require pre-creation in Odoo before migration begins. We use the ir.model.fields API to create custom fields with the correct field type (char, text, integer, float, boolean, date, datetime, selection, many2one, one2many, many2many) matched from MARS field types. Custom fields are created in the Odoo target database before any data import to avoid import-time validation errors.
MARS
Attachment
Odoo CRM
ir.attachment
1:1MARS file attachments linked to Contact, Company, or Deal records map to Odoo ir.attachment. The attachment name, mimetype, and binary content (datas as base64) migrate. Attachments are linked to their parent record via res_model (res.partner or crm.lead) and res_id. We export attachments separately as binary files referenced by URL or file path, then attach via XML-RPC after the parent record exists in Odoo.
MARS
Note
Odoo CRM
mail.message
1:1MARS notes (free-text records separate from activities) map to Odoo mail.message with subtype = 'note' to distinguish from email-type messages. Note body preserves HTML formatting. Notes linked to Contact, Company, or Deal associate via res_model and res_id. Notes without a parent record are linked to the user's res.partner record as a general note.
| MARS | Odoo CRM | Compatibility | |
|---|---|---|---|
| Contact | res.partner (individual)1:1 | Fully supported | |
| Company | res.partner (company)1:1 | Fully supported | |
| Deal | crm.lead (opportunity)1:1 | Fully supported | |
| Deal Stage | crm.stagelossy | Fully supported | |
| Pipeline | crm.team + crm.stage poollossy | Fully supported | |
| Owner | res.users1:1 | Fully supported | |
| Activity: Email | mail.message1:1 | Fully supported | |
| Activity: Call | crm.activity1:1 | Fully supported | |
| Activity: Meeting | calendar.event1:1 | Fully supported | |
| Activity: Task | project.task or crm.activitylossy | Fully supported | |
| Tag | crm.tag + crm.lead.tag.rel1:1 | Fully supported | |
| Custom Field | ir.model.fieldslossy | Fully supported | |
| Attachment | ir.attachment1:1 | Fully supported | |
| Note | mail.message1: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.
MARS gotchas
Low public information
Vendor-implemented deployments vary widely
No public API documented
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 data audit
We audit the MARS database across all primary objects (Contacts, Companies, Deals, Activities, Attachments) and custom fields. We extract record counts, identify null rates per field, map pipeline and stage configurations, and assess the activity history volume. We pair this with a review of the target Odoo configuration: edition (Community self-hosted, Odoo.sh cloud, or Odoo Online), installed modules, existing custom fields, and user count. The discovery output is a written migration scope document listing all objects, record counts, custom field definitions, and a preliminary field-mapping matrix.
Schema design and res.partner split planning
We design the Odoo destination schema based on the MARS data audit. This includes creating Odoo custom fields (via ir.model.fields) to match MARS custom fields, configuring crm.team records for each MARS pipeline, creating crm.stage records with probabilities for each pipeline stage, and designing the res.partner split plan that determines which MARS Contact records become company partners versus individual contacts. The schema design is deployed to the target Odoo instance (Odoo.sh, self-hosted XML-RPC, or Odoo Online database) in a pre-migration setup phase.
Data cleansing and normalization
We run a data quality pass on the MARS export before transformation. This includes deduplication (resolving contacts with identical email addresses), phone number normalization (removing non-numeric characters, adding country code prefixes), date format standardization to ISO 8601, currency value rounding to two decimal places, and null field handling (empty strings converted to False where Odoo expects null). We produce a data quality report showing duplicate counts, null rates, and format violation counts before migration begins.
Sandbox migration and reconciliation
We run a full migration into the target Odoo instance using a test environment (Odoo.sh staging, sandbox database, or clone of the production database). The customer reconciles record counts (Contacts in res.partner, Deals in crm.lead, Activities in mail.message), spot-checks 25-50 records per object against the MARS source, and validates that pipeline stage assignments, owner assignments, and custom field values match. Any mapping corrections are made before production migration. This step runs in one to two weeks.
Production migration in dependency order
We run production migration in record-dependency order: crm.team and crm.stage (required for opportunity team_id and stage_id), res.partner company records, res.partner contact records (with parent_id linking to company), crm.lead opportunities (with partner_id, team_id, stage_id, and user_id resolved), crm.tag tag records, activity history via XML-RPC batches (mail.message, crm.activity, calendar.event), project.task if selected, ir.attachment for files. Each phase emits a row-count reconciliation report showing imported count, skipped count (with reasons), and error count before the next phase begins.
Cutover, validation, and automation inventory handoff
We freeze MARS write access during cutover, run a final delta migration of any records modified during the migration window, then enable Odoo as the system of record. We deliver the workflow, automation, and email template inventory document to the customer's admin team with Odoo Studio equivalents noted. We support a one-week hypercare window to resolve any post-migration data reconciliation issues reported by the Odoo users. We do not rebuild MARS workflows as Odoo automated actions inside the migration scope; that work is documented and handed off as a separate engagement.
Platform deep dives
MARS
Source
Strengths
Weaknesses
Odoo CRM
Destination
Strengths
Weaknesses
Complexity grading
Moderate CRM migration. 8 of 8 objects need a mapping; the rest are 1:1.
Overall complexity
Moderate migration
Derived from compatibility, mapping clarity, API constraints, and data volume across MARS and Odoo CRM.
Object compatibility
8 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
MARS: Not publicly documented..
Data volume sensitivity
MARS 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 MARS to Odoo CRM migration scoping. Not seeing yours? Book a call.
Walk through your MARS 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 MARS
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.