CRM migration
Field-level mapping, validation, and rollback between ContactWise CRM and Odoo CRM. We move data and schema; workflows are rebuilt natively in Odoo CRM.
ContactWise CRM
Source
Odoo CRM
Destination
Compatibility
9 of 12
objects map 1:1 between ContactWise CRM and Odoo CRM.
Complexity
BStandard
Timeline
4-6 weeks
Overview
Moving from ContactWise CRM to Odoo CRM is a migration from a UK-based contact-center-focused CRM to an open-source ERP suite where the CRM module is one application among many. ContactWise stores customer records as Contacts, Leads, and Opportunities; Odoo models the same data as crm.lead records with an is_opportunity flag, with a separate res.partner record serving as the unified contact and account anchor. Pipeline stage names and probabilities must be recreated manually in Odoo because Odoo uses a Kanban-stage architecture with one default pipeline unless additional modules or Studio customization creates multiple pipelines. ContactWise does not publish a documented REST API for its CRM module, so export relies on the platform's native export function, which we supplement with direct database access where the customer has provisioned it. Workflow automation rules, service desk ticket routing logic, and time-based reminder triggers do not migrate as functional code; we deliver a complete written inventory for your Odoo admin to rebuild using Odoo Automations and Studio.
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 ContactWise 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.
ContactWise CRM
Contact
Odoo CRM
res.partner
1:1ContactWise Contacts map directly to Odoo res.partner records with partner_type set to 'contact'. The ContactWise contact_name becomes res.partner.name; email, phone, mobile, website, and address fields map to their Odoo equivalents. Custom contact properties on ContactWise require pre-creation of custom fields in Odoo via Studio or direct field definition. ContactWise stores purchase history and demographics as related properties; these migrate as custom fields on res.partner with type transformation (for example, multi-select picklists convert to Odoo char or many2many tags). res.partner is the central record; all other CRM objects in Odoo reference it via partner_id.
ContactWise CRM
Lead
Odoo CRM
crm.lead
1:1ContactWise Leads map to Odoo crm.lead records with type = 'lead' (as opposed to type = 'opportunity'). Lead status and source attribution from ContactWise map to crm.lead stage_id and source_id respectively. The ContactWise lead_name becomes crm.lead.name. We resolve partner_id by matching the ContactWise contact associated with the Lead against the imported res.partner records. If the Lead has no associated Contact, the lead is imported without a partner_id and the Odoo admin links it during review.
ContactWise CRM
Opportunity
Odoo CRM
crm.lead (type=opportunity)
1:1ContactWise Opportunities map to Odoo crm.lead records with type = 'opportunity'. The opportunity name maps to name, amount maps to planned_revenue, expected close date maps to date_deadline, and owner assignment maps to user_id via email matching to Odoo res.users. Stage mapping is handled via the Pipeline Stage configuration step. The ContactWise deal value and stage are preserved in the stage_id and tag_ids fields.
ContactWise CRM
Companies/Accounts
Odoo CRM
res.partner (partner_type=company)
1:1ContactWise Companies map to Odoo res.partner records with partner_type set to 'company'. Company name maps to name; registered address, phone, and website map to their Odoo equivalents. res.partner records with partner_type=company serve as the parent record for res.partner records with partner_type=contact (individual contacts under a company account). We create Company records before Contact import to satisfy the parent_id lookup during Contact insert.
ContactWise CRM
Pipeline Stage
Odoo CRM
crm.stage
lossyContactWise pipeline stage names and order are documented during discovery and mapped to Odoo crm.stage records within the relevant crm.team. Stage probability percentages from ContactWise map to Odoo stage sequence and probability fields. Odoo uses a Kanban-stage architecture; each stage is tied to a crm.team (sales team). We create stage mapping documentation and apply the mapping during the Opportunity import phase.
ContactWise CRM
Service Desk Tickets
Odoo CRM
helpdesk.ticket
1:1ContactWise service desk tickets map to Odoo helpdesk.ticket records. Ticket subject maps to name; ticket state maps to stage_id (Odoo Helpdesk stages include New, In Progress, Pending, Solved, Closed); priority maps to priority. We perform field-level mapping for every ContactWise ticket attribute because the field schemas differ substantially. Ticket-to-contact association is preserved via partner_id linking the migrated res.partner record. Conversations and comments on tickets migrate as mail.message records attached to the helpdesk.ticket. Odoo Helpdesk must be installed as an additional app on top of the base CRM module.
ContactWise CRM
Time Entries
Odoo CRM
account.analytic.line
1:1ContactWise time entries associated with Contacts, Tickets, or Projects do not map to a standard Odoo CRM object. In Odoo's base CRM module, time tracking is not native. If the customer has Odoo Timesheets or Project management installed, time entries migrate to account.analytic.line with project_id, task_id, name (description), unit_amount, and partner_id linked to the associated res.partner. If Odoo Timesheets is not in scope, we export time entries to a structured CSV and document the recommended Odoo configuration to activate the timesheet module post-migration.
ContactWise CRM
Documents
Odoo CRM
ir.attachment + linked via res_model
1:1ContactWise documents and attachments associated with Contacts, Opportunities, or Tickets migrate as Odoo ir.attachment records linked via res_model and res_id to the corresponding Odoo record (res.partner, crm.lead, or helpdesk.ticket). We export files to cloud storage and create attachment records pointing to the stored files. Attachment migration requires careful path mapping to preserve the association between the file and the parent record in Odoo.
ContactWise CRM
Custom Contact Properties
Odoo CRM
Custom fields on res.partner via Studio
lossyContactWise custom properties on Contact and other objects do not always correspond to standard fields in Odoo res.partner. We identify every custom property during scoping, create matching fields in Odoo via Studio (or direct ir.model.fields definition) before import, and apply value transformations where data types differ. Multi-select picklists convert to Odoo char fields or many2many tags depending on the cardinality of values. Date fields use the Odoo-expected datetime format. Custom fields are created in a development or sandbox Odoo environment before production migration.
ContactWise CRM
Workflow Rules
Odoo CRM
Odoo Automations (documented, not migrated)
lossyContactWise Workflow rules store automation logic (triggers, conditions, actions) as platform configuration and do not export as records. We document every active ContactWise workflow during discovery: trigger type, conditions, and actions. This inventory is delivered to the customer as a written handoff document. The Odoo admin rebuilds equivalent automation in Odoo using Studio Automations or server actions. Time-based reminder triggers in ContactWise have no direct Odoo equivalent and are flagged explicitly in the inventory for manual design decisions.
ContactWise CRM
Owner
Odoo CRM
res.users
1:1ContactWise Owners map to Odoo res.users records. We resolve owners by email match against the Odoo destination database. Any ContactWise Owner without a matching res.users record is held in a reconciliation queue; the customer's Odoo admin provisions the missing user before record import resumes. Active/inactive status in ContactWise maps to active=True/False in Odoo res.users.
ContactWise CRM
Engagements: Notes
Odoo CRM
mail.message
1:1ContactWise note engagements map to Odoo mail.message records linked to the parent record via res_model and res_id. The note body migrates as mail.message.body (HTML) and displays in the Odoo chatter on the parent record (res.partner, crm.lead, or helpdesk.ticket). We preserve the original timestamp in mail.message.date and set message_type to 'comment'.
| ContactWise CRM | Odoo CRM | Compatibility | |
|---|---|---|---|
| Contact | res.partner1:1 | Fully supported | |
| Lead | crm.lead1:1 | Fully supported | |
| Opportunity | crm.lead (type=opportunity)1:1 | Fully supported | |
| Companies/Accounts | res.partner (partner_type=company)1:1 | Fully supported | |
| Pipeline Stage | crm.stagelossy | Fully supported | |
| Service Desk Tickets | helpdesk.ticket1:1 | Mapping required | |
| Time Entries | account.analytic.line1:1 | Mapping required | |
| Documents | ir.attachment + linked via res_model1:1 | Mapping required | |
| Custom Contact Properties | Custom fields on res.partner via Studiolossy | Fully supported | |
| Workflow Rules | Odoo Automations (documented, not migrated)lossy | Fully supported | |
| Owner | res.users1:1 | Fully supported | |
| Engagements: Notes | 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.
ContactWise CRM gotchas
Workflow rules do not export as records
Service desk tickets require non-standard field mapping
API documentation is not publicly available for the CRM module
Custom contact properties may require manual field creation in destination
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 export feasibility assessment
We audit the ContactWise CRM account to identify all objects in scope: Contacts, Leads, Opportunities, Accounts/Companies, service desk tickets, time entries, documents, and custom properties. Because ContactWise does not publish a CRM REST API, we assess the completeness and format of the native export function during discovery. If the customer has provisioned direct database access, we document the table schema and relationships to supplement the native export. We deliver a written migration scope that identifies export gaps, custom field candidates, pipeline count, ticket volume, and any objects that will require manual post-migration cleanup.
Odoo environment provisioning and schema design
We create an Odoo Sandbox environment (or use the customer's existing Odoo instance in developer mode) and install the required apps: CRM, Helpdesk (if tickets are in scope), and any additional modules needed for time entries (Project/Timesheets) or document management. We design the destination schema: custom fields on res.partner and crm.lead via Studio, crm.stage records for each ContactWise pipeline stage with correct sequence and probability, crm.team sales team structure matching ContactWise owner teams, and helpdesk.team and helpdesk.stage records if the Helpdesk module is activated. Schema is validated in the sandbox before any production work begins.
Field mapping documentation and data transformation
We produce a field-by-field mapping document for every object in scope. Standard fields (name, email, phone, address) map directly. Custom ContactWise properties map to the pre-created custom fields on res.partner or crm.lead. Pipeline stages map to crm.stage records using the stage mapping table produced during discovery. Ticket fields map to helpdesk.ticket fields using the explicit field-level mapping. Time entries map to account.analytic.line if Odoo Timesheets is in scope, otherwise exported as structured CSV. Any data type transformations (date formats, multi-select to tags, numeric precision) are documented as transformation rules in the mapping document.
Sandbox migration and reconciliation
We run a full migration into the Odoo sandbox using production-equivalent data volumes. The customer's project lead reviews record counts (Contacts in, Leads in, Accounts in, Opportunities in, Tickets in), spot-checks 25-50 records against the ContactWise source, and validates that pipeline stage names, owner assignments, and custom field values are correctly mapped. Any mapping corrections are applied to the transformation rules and the sandbox migration is re-run. The customer signs off on the sandbox results before we proceed to production.
User provisioning and owner reconciliation
We extract every distinct ContactWise Owner referenced on Contact, Lead, Opportunity, and Ticket records and match by email against the Odoo res.users table. Owners without a matching Odoo user are placed in a reconciliation queue. The customer's Odoo admin provisions any missing users in Odoo (assigning appropriate sales team and helpdesk team memberships) before record import proceeds. Migration cannot proceed past this step because crm.lead.user_id and helpdesk.ticket.user_id references require a valid res.users record.
Production migration in dependency order
We run the production migration in record-dependency order: res.partner (Companies first, then Contacts), crm.lead (Leads then Opportunities with stage_id and user_id resolved), helpdesk.ticket (with partner_id resolved from the res.partner import), account.analytic.line (if Timesheets is in scope), mail.message notes (linked via res_model and res_id to the migrated parent records), and ir.attachment document links. Each phase emits a row-count reconciliation report. We run the native ContactWise export, apply the transformation rules, and load into Odoo using the XML-RPC API with batch chunking and error logging. Any records that fail validation are written to a reject log for manual review.
Cutover, validation, and workflow handoff
We freeze writes to ContactWise during cutover, run a final delta migration of any records created or modified during the migration window, then mark Odoo as the system of record. We validate record counts across all objects, confirm pipeline stage distribution in Odoo matches the source, and spot-check 20 records with the customer. We deliver the ContactWise workflow inventory document to the customer's Odoo admin for rebuild using Odoo Studio Automations or server actions. We provide a one-week hypercare window to resolve any reconciliation issues raised by the team. We do not rebuild ContactWise workflows inside the migration scope; that is a separate engagement.
Platform deep dives
ContactWise CRM
Source
Strengths
Weaknesses
Odoo CRM
Destination
Strengths
Weaknesses
Complexity grading
Standard CRM migration. All 8 core objects map 1:1 between ContactWise CRM and Odoo CRM.
Overall complexity
Standard migration
Derived from compatibility, mapping clarity, API constraints, and data volume across ContactWise CRM and Odoo CRM.
Object compatibility
All 8 core objects map 1:1 between ContactWise CRM and Odoo CRM.
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
ContactWise CRM: Not publicly documented.
Data volume sensitivity
ContactWise 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 ContactWise CRM to Odoo CRM migration scoping. Not seeing yours? Book a call.
Walk through your ContactWise 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 ContactWise 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.