CRM migration
Field-level mapping, validation, and rollback between OneHash CRM and Odoo CRM. We move data and schema; workflows are rebuilt natively in Odoo CRM.
OneHash CRM
Source
Odoo CRM
Destination
Compatibility
12 of 12
objects map 1:1 between OneHash CRM and Odoo CRM.
Complexity
BStandard
Timeline
3-5 weeks
Overview
Moving from OneHash CRM to Odoo CRM is a migration between two ERP-forked platforms with overlapping ancestry but divergent object models. OneHash inherits ERPNext's DocType architecture — a document-centric model where Leads, Contacts, Customers, Quotations, and Sales Orders are separate document types with rich custom-field support. Odoo uses its own object hierarchy where Leads and Opportunities share the crm.lead model, Contacts are res.partner records, and Quotations and Sales Orders are both sale.order records distinguished by state. We handle the schema translation between these models, including the res.partner split between company-level and person-level records, the DocType-to-object type resolution, and the custom field mapping that OneHash's ERPNext inheritance makes necessary. Attachment migration, INR-to-USD pricing conversion during scoping, and Odoo's XML-RPC API access requirements are surfaced early so teams are not surprised at cutover.
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 OneHash 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.
OneHash CRM
Lead
Odoo CRM
crm.lead
1:1OneHash Lead DocType maps directly to Odoo crm.lead with type=lead. We map lead_name to name, status to stage_id (with a stage-name map built from Odoo's default CRM stages), source to source_id, and notes to description. Custom fields on the Lead DocType migrate to custom crm.lead fields (ir.model.fields with model=crm.lead) created before import. Lead-to-Contact conversion linkage is preserved as a tag or note so the relationship is auditable in Odoo even though Odoo handles the conversion differently.
OneHash CRM
Contact
Odoo CRM
res.partner
1:1OneHash Contact records map to Odoo res.partner where is_company=False. We map first_name and last_name to firstname and lastname, email to email, phone to phone, and organization linkage to parent_id (pointing to the Customer partner record). Contact addresses nested within the Contact DocType in OneHash extract to separate res.partner address records linked via type (invoice, delivery, contact). OneHash contact custom fields map to res.partner custom fields.
OneHash CRM
Customer
Odoo CRM
res.partner
1:1OneHash Customer (organization-level) DocType maps to Odoo res.partner where is_company=True. The customer name maps to name, billing and shipping addresses map to child partner records with type=invoice or type=delivery, and any linked Contacts attach via child_ids. OneHash Customer custom fields (industry, annual_revenue, company_size) map to res.partner custom fields on the company partner.
OneHash CRM
Opportunity
Odoo CRM
crm.lead
1:1OneHash Opportunity DocType maps to Odoo crm.lead with type=opportunity. The opportunity amount maps to planned_revenue, probability to probability (0-100 integer), stage to stage_id (via a stage-name map), party information to partner_id (res.partner lookup resolved after the Customer/Contact migration phase), and pipeline assignment to team_id. The pipeline stage ordering migrates via a stage-sequence map applied after the crm.lead import completes.
OneHash CRM
Quotation
Odoo CRM
sale.order
1:1OneHash Quotation DocType maps to Odoo sale.order in state=draft (Odoo treats quotations as draft sale orders). Quotation line items (Items with pricing, tax templates, and quantities) map to sale.order.line with Product2 references resolved after the product catalog migration phase. Tax templates from OneHash map to Odoo account.tax. The quotation-to-opportunity linkage is preserved in sale.order.description as a reference tag since Odoo does not natively store the opportunity link on sale.order; this is documented in the migration inventory for the customer's admin to configure via Odoo's CRM link if needed.
OneHash CRM
Sales Order
Odoo CRM
sale.order
1:1OneHash Sales Order DocType maps to Odoo sale.order in state=sale (confirmed order). Order item rows map to sale.order.line with quantity, price_unit, discount, and tax resolved. OneHash order status flags (delivery status, billing status) have no direct Odoo equivalents on sale.order; we preserve these as custom fields so the customer's admin can map them to stock.picking state or account.move state post-migration if needed.
OneHash CRM
Item
Odoo CRM
product.product
1:1OneHash Item DocType maps to Odoo product.product. Standard fields (item_name to name, item_code to default_code, unit_of_measure to uom_id) migrate directly. Custom Item fields specific to the business (weight, dimensions, supplier, HS codes) map to product.product custom fields created before import. OneHash pricing data (price_list rates) maps to product.pricelist.item entries against the standard Odoo pricelist.
OneHash CRM
Project
Odoo CRM
project.project
1:1OneHash Project DocType maps to Odoo project.project. Project name, description, start and end dates, and status (open vs completed) migrate directly. Tasks within the project map to project.task with parent_id hierarchy preserved. Task assignees (Employee DocType references) map to project.task user_id via the Odoo User resolution pass. Open vs completed status is preserved; task comments map to project.task description notes.
OneHash CRM
Employee
Odoo CRM
hr.employee
1:1OneHash Employee DocType maps to Odoo hr.employee. Designation maps to job_id (linked to hr.job), department to department_id (linked to hr.department), and compensation records to hr.contract on the employee. We preserve org-chart parent_id relationships and effective-dated contract records as a separate mapping layer. Employee custom fields migrate to hr.employee custom fields created in the destination Odoo database before import.
OneHash CRM
Chart of Accounts
Odoo CRM
account.account
1:1OneHash Chart of Accounts DocType maps to Odoo account.account. Account names, types (asset, liability, equity, income, expense), and parent-child hierarchy (parent_account) migrate directly. Account numbers are preserved in code where the destination supports them. This migration scope is scoped to the account master records only; Odoo requires chart of accounts initialization via the setup wizard which the customer's accountant completes; the migration provides the account list for manual entry or CSV import via Odoo's accounting setup.
OneHash CRM
Custom DocType
Odoo CRM
Custom Object
1:1OneHash custom DocTypes (ERPNext-style documents created via Customize Form) require schema discovery before mapping. We introspect each custom DocType's field definitions via the OneHash API during the discovery pass, then pre-create matching Odoo models (ir.model), fields (ir.model.fields), and menu items in the destination Odoo database. Custom DocType relationships to standard DocTypes (e.g., a custom field on Lead linking to a custom Customer extension) map to Odoo many2one or many2many fields created alongside the standard object mapping.
OneHash CRM
Attachment
Odoo CRM
ir.attachment
1:1Documents attached to any OneHash DocType migrate as ir.attachment records in Odoo. We extract the binary blob, preserve the original filename, and link via res_model and res_id to the migrated parent record (crm.lead, res.partner, sale.order, etc.). Large attachments (over 10 MB) require chunked download from OneHash and chunked upload to Odoo. File storage backend in the destination Odoo instance (file on disk, S3, database) is confirmed during scoping so that the migration pipeline is configured correctly before attachments are processed.
| OneHash CRM | Odoo CRM | Compatibility | |
|---|---|---|---|
| Lead | crm.lead1:1 | Fully supported | |
| Contact | res.partner1:1 | Fully supported | |
| Customer | res.partner1:1 | Fully supported | |
| Opportunity | crm.lead1:1 | Fully supported | |
| Quotation | sale.order1:1 | Fully supported | |
| Sales Order | sale.order1:1 | Fully supported | |
| Item | product.product1:1 | Fully supported | |
| Project | project.project1:1 | Fully supported | |
| Employee | hr.employee1:1 | Fully supported | |
| Chart of Accounts | account.account1:1 | Mapping required | |
| Custom DocType | Custom Object1:1 | Fully supported | |
| Attachment | ir.attachment1: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.
OneHash CRM gotchas
OneHash is a fork of ERPNext with Indian-market pricing
Annual billing is mandatory for paid plans above the free tier
No publicly documented API rate limits or bulk export endpoints
Custom Fields are DocType-specific and require schema discovery
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 DocType inventory
We audit the source OneHash instance across all active DocTypes, custom fields per DocType, record counts per DocType, attachment volumes, and any custom scripts or server-side hooks that modify DocType behavior. We run the schema discovery pass against each DocType's API endpoint to enumerate custom field names, types, and options. We also confirm the OneHash API key scope and request elevated read access if the instance exceeds 10,000 records. The discovery output is a written DocType inventory, custom field matrix, and migration scope document that the customer reviews before we proceed.
Odoo schema design and custom field provisioning
We design the destination Odoo schema by mapping each OneHash DocType to its Odoo equivalent object (crm.lead, res.partner, sale.order, product.product, etc.), creating any required custom fields via ir.model.fields, and configuring Odoo-specific settings like CRM team, stage definitions, sales team, and warehouse before any data is imported. Custom DocTypes in OneHash require us to create new Odoo models (ir.model) in the destination database, which is a schema creation step that requires the migration user to have technical access or the customer's Odoo admin to pre-provision. Schema is validated in an Odoo test database before production migration begins.
Odoo API access and rate-limit characterization
We configure Odoo XML-RPC API access for the migration user (database, login, password, and model access permissions). We characterize Odoo's rate-limit behavior during a dry-run pass to establish safe batch sizes and retry intervals. We also confirm the destination Odoo edition (Community self-hosted vs Odoo Online vs Odoo.sh) because API access methods and rate limits differ by deployment type. If the destination is Odoo Community self-hosted, we coordinate with the customer's technical team on server resource headroom for bulk import operations.
Owner and user reconciliation
We extract every distinct owner referenced on OneHash records (Leads, Contacts, Opportunities, Quotations, Projects) and match them against the destination Odoo User list. OneHash stores owner as a User DocType reference; Odoo uses res.users for owner_id on crm.lead and sale.order. Owners without a matching Odoo User go to a reconciliation queue for the customer's admin to provision. This step gates the entire migration because OwnerId references are required on most Odoo standard records and cannot be nulled out without affecting accountability reporting.
Production migration in dependency order
We run production migration in strict dependency order: res.partner company records first (Customer DocType), res.partner contact records second (Contact DocType with parent_id resolved), product.product records third, account.account records fourth, crm.lead records fifth (Lead and Opportunity DocTypes mapped to crm.lead with type split), sale.order records sixth (Quotation DocType to draft sale.order, Sales Order DocType to confirmed sale.order), project.project and project.task seventh, hr.employee eighth, custom object records ninth, and ir.attachment records last with res_model and res_id linkage resolved to the migrated parent. Each phase emits a row-count reconciliation report before the next phase begins.
Cutover, validation, and automation rebuild handoff
We freeze OneHash writes during cutover, run a final delta migration of any records created or modified during the migration window, then enable Odoo as the system of record. We deliver a written inventory of every active OneHash workflow, automation, and DocType-level script with a recommended Odoo equivalent (studio action, server action, or base.automation rule). We do not rebuild OneHash automations as Odoo actions inside the migration scope — that work requires Odoo-specific configuration by the customer's admin or an Odoo partner. We support a one-week hypercare window where we resolve any record linkage issues or field mapping discrepancies raised by the customer's team.
Platform deep dives
OneHash 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 OneHash 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
OneHash CRM: Not publicly documented — discovered dynamically during migration.
Data volume sensitivity
OneHash 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 OneHash CRM to Odoo CRM migration scoping. Not seeing yours? Book a call.
Walk through your OneHash 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 OneHash 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.