CRM migration
Field-level mapping, validation, and rollback between Daylite and Odoo CRM. We move data and schema; workflows are rebuilt natively in Odoo CRM.
Daylite
Source
Odoo CRM
Destination
Compatibility
9 of 12
objects map 1:1 between Daylite and Odoo CRM.
Complexity
BStandard
Timeline
3-4 weeks
Overview
Moving from Daylite to Odoo CRM is a cross-ecosystem transition from a Mac-native CRM backed by a Cocoa SQLite ORM to a web-based Python ERP-adjacent CRM accessed over XML-RPC. Daylite stores its rich object graph — People, Companies, Opportunities, Projects, Appointments, Tasks, Notes, and Groups — as a compressed archive of CSV tables linked by integer foreign keys. Odoo CRM uses the Odoo ORM (res.partner, crm.lead, project.project, project.task, calendar.event) with external ID lookups on import. We parse the Daylite export, reconstruct the foreign-key relationships, and write them into Odoo's import-compatible structure. The main structural differences are that Odoo separates the CRM lead/opportunity pipeline from project management (which lives in a separate Odoo app), pipeline stages are a centrally managed taxonomy rather than per-record freeform strings, and Billings Pro data cannot be migrated because it lives in a separate application database. Workflows and automations are documented for manual rebuild 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 Daylite 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.
Daylite
People
Odoo CRM
Contact (res.partner)
1:1Daylite People map to Odoo res.partner records. A Person with a linked Company maps as a child Contact (contact_type = contact) under the parent Partner that represents the Company. A standalone Person without a Company link maps as a Partner with partner_type = individual. We extract the first_name, last_name, email, phone, mobile, and address fields from the Daylite export and map them to Odoo's name, email, phone, mobile, and address fields. Custom fields on People create custom res.partner fields in Odoo before import.
Daylite
Companies
Odoo CRM
Partner (res.partner, partner_type = company)
1:1Daylite Company records map to Odoo res.partner with partner_type = company. The Daylite Company name becomes the Partner name, and the Company address maps to the Partner address fields. Every child Contact (from People) references this Partner as parent_id, preserving the Person-to-Company relationship. Company-level custom fields create custom res.partner fields on the company-type Partner record.
Daylite
Opportunities
Odoo CRM
CRM Lead / Opportunity (crm.lead)
1:1Daylite Opportunities map to Odoo crm.lead records. The Opportunity name becomes the Lead subject, the value maps to expected_revenue, and the linked Person and Company resolve to partner_id (the Contact and parent Partner respectively). The Daylite stage name — which is freeform text per record — requires normalization before import; see the Pipeline Stages mapping. We flag won and lost stages and set the crm.lead stage accordingly during the transform.
Daylite
Pipeline Stages
Odoo CRM
CRM Stage (crm.stage)
lossyDaylite stores Opportunity stage names as plain text strings in each Opportunity record, not in a centralized taxonomy. We extract all distinct stage strings from the export, deduplicate them, and present them as a stage normalization table for the customer to map to Odoo's crm.stage taxonomy. We then configure each mapped Odoo stage with the corresponding sequence number and probability percentage from Daylite. Any typos or variant names in historical records are normalized at migration time to the agreed stage targets.
Daylite
Appointments
Odoo CRM
Calendar Event (calendar.event)
1:1Daylite Appointments map to Odoo calendar.event records. We preserve the UTC start and end timestamps from Daylite, the all-day flag, and the location string. The linked Person ID from Daylite resolves to the corresponding res.partner in Odoo and is stored as an attendee on the Event. Daylite category strings are extracted as distinct values and mapped to Odoo calendar event types or stored as a custom field, depending on the customer's preference. Recurring appointments require a separate normalization step to map the recurrence rule into Odoo's RRULE format.
Daylite
Tasks
Odoo CRM
Task (project.task)
1:1Daylite Tasks map to Odoo project.task records. Standalone Tasks in Daylite (not linked to a Project) create project.task records under a default Odoo project designated for unscheduled work. Tasks linked to a Daylite Project reference the corresponding project.project record in Odoo via project_id, and sub-tasks map with parent_id set to the parent project.task. Task status, priority, and due date map directly; assignee resolves from Daylite Owner to Odoo User by email match.
Daylite
Notes
Odoo CRM
Note (mail.message with subtype note)
1:1Daylite Notes map to Odoo mail.message records with subtype note. The message body migrates as HTML-compatible text, preserving formatting where Daylite's rich text format maps cleanly to Odoo's mail composer HTML. The linked object type and ID from Daylite determine the res_model and res_id on the Odoo message. We reconstruct the Note threading by preserving parent_id references where Daylite has note-in-note relationships.
Daylite
Groups
Odoo CRM
CRM Tag (ir.model.data / crm.tag)
lossyDaylite static Groups are recreated as Odoo CRM tags. Each Daylite Group becomes a crm.tag record, and the Group membership (Person-to-Group mapping) becomes tag IDs on the res.partner record. Groups attached to Companies or Projects create tag assignments on those respective objects. The customer chooses whether Daylite Groups appear as CRM tags, partner categories, or a combination during scoping.
Daylite
Custom Fields
Odoo CRM
Custom Fields (ir.model.fields)
lossyDaylite stores custom field definitions in a separate metadata table and values in the record tables. We extract both during export parsing, present a custom field mapping worksheet for the customer to confirm each field's Odoo target model and field type (char, float, date, boolean, selection, many2one), then pre-create the Odoo custom fields via the ORM or CSV import before populating values. Fields that reference other Daylite records require external ID resolution to establish the Odoo many2one reference.
Daylite
Attachments
Odoo CRM
Attachment (ir.attachment)
1:1Daylite bundles attachments as a flat folder in the compressed export with filenames referencing the parent object type and ID. We parse the filename structure to determine the parent Odoo model (res.partner, crm.lead, project.task, calendar.event), resolve the corresponding record ID in Odoo, and reattach the file using ir.attachment with the correct res_model, res_id, and original filename. Attachments larger than the Odoo file size limit require chunked upload via XML-RPC.
Daylite
Projects
Odoo CRM
Project (project.project)
1:1Daylite Project records map to Odoo project.project. The Daylite Project status, start date, and end date map to project.project stage_id, date_start, and date. Budget fields from Daylite — or from the iOSXpert Time&Budget plugin if present — map to Odoo analytic.account fields for budget tracking. Linked Tasks and Appointments within the Project reference the project.project record via project_id, maintaining the parent-child hierarchy in Odoo. Daylite project budgets stored as cost thresholds require a custom field mapping to Odoo's planned hours or analytic account budget limits.
Daylite
iOSXpert Plugin Data
Odoo CRM
Custom Fields / Project.analytic.account
1:1iOSXpert plugins (Time&Budget, FinanceConnector) write data into additional Daylite database tables. These tables appear in the export only if the plugin was installed and active at export time. We audit the exported table list for plugin signatures during scoping and flag any absent plugin tables for confirmation. Where plugin tables are present, their fields map to custom fields on the corresponding Odoo objects (project.task for Time&Budget hours, project.analytic.account for budget thresholds). Plugin data cannot be migrated if the plugin was not installed at export time.
| Daylite | Odoo CRM | Compatibility | |
|---|---|---|---|
| People | Contact (res.partner)1:1 | Fully supported | |
| Companies | Partner (res.partner, partner_type = company)1:1 | Fully supported | |
| Opportunities | CRM Lead / Opportunity (crm.lead)1:1 | Fully supported | |
| Pipeline Stages | CRM Stage (crm.stage)lossy | Mapping required | |
| Appointments | Calendar Event (calendar.event)1:1 | Fully supported | |
| Tasks | Task (project.task)1:1 | Fully supported | |
| Notes | Note (mail.message with subtype note)1:1 | Fully supported | |
| Groups | CRM Tag (ir.model.data / crm.tag)lossy | Fully supported | |
| Custom Fields | Custom Fields (ir.model.fields)lossy | Mapping required | |
| Attachments | Attachment (ir.attachment)1:1 | Mapping required | |
| Projects | Project (project.project)1:1 | Fully supported | |
| iOSXpert Plugin Data | Custom Fields / Project.analytic.account1:1 | Mapping required |
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.
Daylite gotchas
Database export download expires after 14 days
Billings Pro self-serve is discontinued, cloud migration required
Plugin-stored data is only exportable if the plugin is installed
Custom field definitions must be manually mapped
Pipeline stage names are plain text, not a managed taxonomy
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 validation
We confirm the Daylite export download link is active and has not expired. We parse the compressed archive, list all exported tables, and audit for plugin table signatures (Time&Budget, FinanceConnector). We extract the custom field definition table and the pipeline stage value list. We assess data quality (duplicate email addresses, missing required fields, date format consistency) and present a scoping worksheet for the customer to confirm which Daylite objects are in scope and whether iOSXpert plugin data should be migrated. The discovery output is a written scope document and migration timeline.
Schema design in Odoo
We design the destination Odoo schema to match the confirmed Daylite data model. This includes creating custom fields on res.partner, crm.lead, project.project, project.task, and calendar.event for any Daylite custom fields confirmed in scope. We configure the CRM pipeline stages in Odoo using the deduplicated and customer-approved stage normalization table. We set up CRM tags to replicate Daylite Group segmentation. We configure the Odoo Project structure to receive Daylite Projects, Tasks, and Appointments. Schema is deployed into a test Odoo environment first for validation before production migration.
Sandbox migration and reconciliation
We run a representative migration into a test Odoo database using the actual Daylite export data. The customer reconciles record counts (People in, Partners in, Opportunities in, Projects in, Activities in), spot-checks 25-50 records against the Daylite source for field accuracy and relationship integrity, and reviews the stage mapping results. Any field mapping corrections, stage normalization adjustments, or custom field targeting decisions are resolved in the test environment before production migration begins.
Owner reconciliation
We extract every distinct Daylite Owner referenced across People, Companies, Opportunities, Projects, and Activities and match them by email against the Odoo destination User list. Owners without a matching Odoo User enter a reconciliation queue. The customer's Odoo administrator provisions any missing Users. Migration cannot advance past the record-import phase until all referenced Owner IDs have a valid Odoo User target or are explicitly remapped to a default user.
Production migration in dependency order
We import records into Odoo in strict dependency order: Users (validated against the reconciliation queue), Partners (from Daylite Companies), Contacts (from Daylite People with parent_id resolved to the Partner), CRM Leads (from Daylite Opportunities with partner_id and stage_id resolved), Projects (with budget fields mapped if Time&Budget data is present), Tasks (with project_id and parent_id resolved), Appointments (as calendar events with attendee resolution), Notes (as mail.message records), Attachments (re-linked via ir.attachment), Tags (created and assigned), and Custom field values (populated on each object after the base record is created). Each phase emits a reconciliation report before the next begins.
Cutover, delta migration, and rebuild handoff
We freeze writes in Daylite at cutover, run a final delta pass for any records modified during the migration window, and set Odoo as the system of record. We deliver a written inventory of all Daylite automations, workflows, and scheduled actions with recommended Odoo equivalents for the customer's administrator to rebuild. We provide a one-week hypercare window to resolve any data integrity issues reported by the sales and operations teams. We do not rebuild Daylite automations as Odoo server actions inside the migration scope.
Platform deep dives
Daylite
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 Daylite 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
Daylite: Not publicly documented as specific numeric quotas; standard SaaS limits assumed and confirmed during scoping.
Data volume sensitivity
Daylite exposes a bulk API — large-volume migrations stream efficiently.
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 Daylite to Odoo CRM migration scoping. Not seeing yours? Book a call.
Walk through your Daylite 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 Daylite
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.