CRM migration

Migrate from Constructor to Odoo CRM

Field-level mapping, validation, and rollback between Constructor and Odoo CRM. We move data and schema; workflows are rebuilt natively in Odoo CRM.

Constructor logo

Constructor

Source

Odoo CRM

Destination

Odoo CRM logo

Compatibility

100%

11 of 11

objects map 1:1 between Constructor and Odoo CRM.

Complexity

BStandard

Timeline

48–72 hours

Rollback included Accuracy guarantee Field-level validation

Overview

What this migration involves

Teams migrate from Constructor CRM to Odoo CRM to consolidate fragmented business tools, escape per-seat pricing at scale, and gain access to Odoo's open-source modular architecture spanning CRM, sales, accounting, inventory, and project management. Constructor CRM stores contacts, companies, deals, tasks, notes, and custom properties in a relatively flat object graph. Odoo CRM models the same data using res.partner (which unifies people and organizations), crm.lead (used both as lead and opportunity), crm.stage for pipeline stages, and project.task for activity tracking. Custom properties defined in Constructor require Odoo custom fields to be pre-created in the database before data can be written. We handle this through Odoo's XML-RPC API using structured mapping scripts per object, validating field-level parity before the full run commits. The migration carries all standard objects with timestamps and ownership preserved, then surfaces custom property definitions and workflow logic as a rebuild reference for Odoo configuration after cutover. FlitStack does not migrate workflows, automations, or email templates — those require manual rebuild in Odoo's Studio or automation tools. A delta-pickup window (24–48 hours) captures in-flight changes during the final cutover so Odoo reflects Constructor's state at go-live.

Field-level fidelity

Every standard and custom field arrives verified.

Schema-aware mapping

AI proposes the map; you confirm before any record moves.

Relationships preserved

Parent–child, lookups, and ownership stay linked.

Full activity history

Calls, emails, meetings — with original timestamps.

Attachments & notes

Documents, uploads, and inline notes move with the record.

Why teams make this switch

Two sides of the same decision

Leaving

Constructor logo

Constructor

What's pushing teams away

  • G2 reviewers report uptime falling below 90% during some periods, which is below the threshold most modern SaaS customers tolerate.
  • Reporting is consistently called out as weak — reviewers note reports are not always available and filters are 'tough to administer and utilize'.
  • Filter management is described as difficult to manage and use effectively, slowing down ad-hoc data analysis and list-building.
  • Customers seeking strong native integrations beyond the listed Salesforce / ClickHomes / OCR / ELO connectors hit gaps and have to commission custom API work.
  • Builders that expand outside ANZ outgrow the platform's regional focus, since progress-claim conventions and tax treatments are tuned for Australian and New Zealand construction practice.

Choosing

Odoo CRM logo

Odoo CRM

What's pulling them in

  • Teams choose Odoo CRM for its modular architecture — one base install with one-click app additions means they can adopt CRM alone and add accounting, inventory, or sales later as the business grows.
  • Small businesses pick Odoo because the Community edition is free and open-source, with no per-user or contact limits, allowing full evaluation before committing to a paid Enterprise tier.
  • The drag-and-drop Kanban pipeline and AI lead scoring are highlighted across G2 reviews as concrete features that make lead management faster and more visual than spreadsheet-based workflows.
  • Odoo's native integration with email, live chat, SMS, VoIP, and WhatsApp means inbound leads from multiple channels feed into a single pipeline without third-party middleware.
  • Companies in retail, supply chain, and construction value that Odoo's CRM module shares the same PostgreSQL database and UI as its ERP modules, eliminating data silos between sales and operations.

Object mapping

How Constructor objects map to Odoo CRM

Each row shows how a Constructor 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.

Constructor

Contact

maps to

Odoo CRM

crm.lead

1:1
Fully supported

Constructor contacts map to Odoo crm.lead records with type='lead' by default. The contact's name splits into firstname and lastname on the Odoo partner; if the contact has no firstname the full name lands in the partner's display_name field. Constructor company_id resolves to an Odoo res.partner record with is_company=True before the contact is written.

Constructor

Company

maps to

Odoo CRM

res.partner

1:1
Fully supported

Constructor companies map directly to Odoo res.partner records with is_company=True set. The partner's address fields (street, city, state, zip, country) are written from Constructor's address block. Parent-company relationships in Constructor map to Odoo's parent_id on res.partner, requiring the parent partner to be migrated first to avoid orphaned links.

Constructor

Deal

maps to

Odoo CRM

crm.lead

1:1
Fully supported

Constructor deals map to Odoo crm.lead with type='opportunity'. The deal's name becomes crm.lead name, amount maps to planned_revenue, close_date becomes date_deadline, and the Constructor owner resolves to crm.lead user_id by email match. Pipeline stage values map to Odoo stage_id via a value-mapping table built during the discovery phase, preserving stage order and probability.

Constructor

Pipeline

maps to

Odoo CRM

crm.team + crm.stage

1:1
Fully supported

Constructor pipelines become Odoo crm.team records, each containing its own ordered stage sequence via crm.stage. Stage names and probabilities map value-by-value. If Constructor has multiple pipelines, each generates a separate crm.team in Odoo so the Kanban board view is scoped correctly. Team assignment on leads must resolve after the team records exist.

Constructor

Custom Property (on Contact)

maps to

Odoo CRM

ir.model.field (res.partner)

1:1
Fully supported

Constructor custom properties on contacts require Odoo custom fields to be created as ir.model.field records on res.partner before data can be loaded. The field name is derived from the Constructor property slug, and field type (char, selection, float, boolean, date) is inferred from the property value type. We generate a field-creation manifest during planning so Odoo is schema-ready before the migration run.

Constructor

Custom Property (on Deal)

maps to

Odoo CRM

ir.model.field (crm.lead)

1:1
Fully supported

Constructor custom properties on deals migrate to Odoo custom fields on crm.lead. Priority, rating, or selection-type properties become selection fields with value maps defined in the field definition. Numeric properties become float fields. Text blobs become char or text depending on expected length. We validate all custom fields are created before opportunity records are written to avoid silent field-missing errors.

Constructor

Task / Activity

maps to

Odoo CRM

project.task

1:1
Fully supported

Constructor tasks, calls, and logged activities map to Odoo project.task records linked to the parent crm.lead via res_id and res_model='crm.lead'. Task type is set from the Constructor activity kind (call, email, meeting, note). Original create_date and write_date are preserved on the task record. Owner resolution uses the same email-match logic as all other objects.

Constructor

Note

maps to

Odoo CRM

note.note

1:1
Fully supported

Constructor notes map to Odoo note.note records. The note's body text and title are written to the note.note fields. If the Constructor note is attached to a specific contact or deal, the Odoo note is linked via res_model and res_id pointing to the corresponding crm.lead or res.partner record. Create and write timestamps are preserved.

Constructor

Attachment / File

maps to

Odoo CRM

ir.attachment

1:1
Fully supported

Constructor file attachments are downloaded from the source platform and re-uploaded to Odoo's ir.attachment table with the correct res_model (crm.lead or res.partner) and res_id pointing to the migrated parent record. The original filename and MIME type are preserved in the attachment's name and mimetype fields. Inline images embedded in notes are extracted and stored as separate attachments.

Constructor

Owner / User

maps to

Odoo CRM

res.users

1:1
Fully supported

Constructor owner_id values are resolved by matching the owner's email address against Odoo res.users records. Unmatched owners are flagged before the migration run; the team either creates Odoo user accounts first or nominates a fallback user to own unmapped records. No record lands in Odoo without a valid user_id — the migration halts on unresolved owners rather than orphaning data.

Constructor

Constructor custom objects

maps to

Odoo CRM

ir.model (custom model)

1:1
Fully supported

Constructor custom objects beyond the standard set map to Odoo custom models created via the Odoo framework (ir.model + ir.model.fields). The migration plan includes the model name, the target model ID, and the full field-list mapping so Odoo is configured before records are written. Associations between custom objects map to Odoo many2one or one2many relations as applicable.

Gotchas + challenges

What specifically takes care here

Platform-specific issues from each side, plus the pair-specific challenges that don't show up on either platform's page on its own.

Constructor logo

Constructor gotchas

High

Reporting and filter limitations make pre-migration data inventory harder

High

Estimating templates and take-offs carry business logic, not just data

Medium

KeyPay payroll data lives in a connected but separate system

Medium

Uptime variability requires staged migration windows

Low

Custom integrations (Salesforce, ClickHomes, OCR, ELO) need separate scoping

Odoo CRM logo

Odoo CRM gotchas

High

Odoo.sh version gating blocks assisted migrations from trial

High

Enterprise modules fail to install on Community after database restore

Medium

Custom module view inheritance breaks between Odoo major versions

Medium

Custom fields risk losing their application context on Community

Low

API access for Community is gated behind the Custom Plan

Pair-specific challenges

  • Odoo custom fields must be created before data can be written to them

    Constructor's custom property system accepts typed key-value pairs on any record without a schema declaration step. Odoo takes the opposite approach: every custom field must be registered as an ir.model.field record in the database before data can be stored in that field. This means the migration plan must include a field-creation manifest derived from Constructor's custom property definitions — mapping each property's data type to the corresponding Odoo field definition — and that manifest must be applied to Odoo before the main record migration runs. If a custom property is discovered during the migration that was not in the original manifest, the record write will fail silently or return an error depending on the API call context. We generate the complete field manifest during the discovery phase and validate all fields exist in Odoo before any data moves.

  • Constructor's separate contact/company model requires partner deduplication in Odoo

    Constructor stores contacts and companies as distinct objects with a many-to-one link from contact to company. Odoo unifies both concepts in res.partner: a partner record with is_company=True represents an organization, and a partner record with is_company=False represents a person, linked to the organization via parent_id. When a Constructor contact has no associated company, it migrates to a standalone res.partner with is_company=False. When a contact does have a company link, the company partner must be migrated first so the parent_id foreign key resolves correctly. Constructor contacts without any name set default to the email address as the partner name in Odoo to avoid blank display_name records.

  • Odoo XML-RPC API batches must be sized to avoid request timeouts on large datasets

    Odoo's external API (xmlrpc/2/object) does not publish per-request record limits, but the underlying PostgreSQL transaction and HTTP worker timeout on self-hosted and Odoo.sh instances impose practical ceilings. Migrations involving more than a few thousand records at a time risk worker restarts if requests are too large or too frequent. We chunk all write operations into batches of 200–500 records per API call, introducing short pauses between batches. For Constructor setups with 500,000+ records, the migration script runs in a staged loop with checkpoint logging so a mid-run interruption can resume from the last committed batch rather than restarting from zero.

  • Constructor workflows, automations, and sequence logic have no Odoo equivalent and must be rebuilt

    Constructor's automation features — workflow rules, conditional triggers, automated task creation, and outbound sequence logic — exist as platform-native constructs with no structural equivalent in Odoo. Odoo's automation model uses Studio-based workflow rules, server actions (ir.actions.server), and base.automation records, but these require manual rebuild. FlitStack exports Constructor's workflow definitions as structured JSON during the discovery phase, providing a rebuild reference for the Odoo admin. This export is delivered alongside the migration data and does not move into Odoo automatically. Teams should plan for a post-migration Odoo configuration sprint to recreate automation logic.

  • Constructor owner IDs resolve by email match, and unmatched owners block record writes

    Every Constructor record with an owner_id requires a corresponding Odoo res.users record identified by email address. If a Constructor owner has no Odoo user account — because the person left the company or was never provisioned — the migration halts on that record rather than writing an orphan. Before the migration run, we generate an unmatched-owner report listing every Constructor user who has no Odoo counterpart. The team either provisions those users in Odoo first or nominates a fallback user to receive those records. No record lands without an assigned user_id on Odoo crm.lead, project.task, or res.partner.

Migration approach

Six steps for a successful Constructor to Odoo CRM data migration

  1. Review Constructor data export and build the field manifest

    We start by reviewing the Constructor data export to identify every object type, standard field, and custom property in use. Each custom property is typed (text, number, date, selection, boolean) and the type is used to generate the corresponding Odoo ir.model.field definition. The field manifest lists the field name, model, and field type for every custom property so Odoo can be schema-configured before any data is written. We also document the pipeline-stage list, owner list, and any N:N associations between objects that require junction-table handling in Odoo.

  2. Configure Odoo custom fields and crm.team structure

    Using the field manifest from step 1, we create all Odoo custom fields on the target models (res.partner and crm.lead) before the migration run. Simultaneously, we configure the crm.team records that correspond to Constructor pipelines, and the crm.stage records within each team that correspond to Constructor pipeline stages. Stage probability values and stage order are applied from the Odoo stage configuration. This step requires an Odoo admin or our team operating with developer-mode access to write the field definitions and stage setup. The migration cannot proceed to data loading until this step is complete.

  3. Resolve owners and seed Odoo users by email match

    We extract the unique owner_id list from Constructor records and cross-reference it against existing Odoo res.users accounts by email. Unmatched owners are flagged in a pre-flight report delivered to the team before the migration window opens. The team either creates Odoo user accounts for those owners or nominates a fallback user. We do not write records with unresolved owners — the migration script halts on missing user mappings rather than silently assigning orphaned records. This step runs before any data is loaded so the user resolution table is complete before record writes begin.

  4. Run a sample migration with field-level diff on 100–500 records

    A representative slice of Constructor records — spanning contacts, companies, deals, tasks, and notes with a mix of custom properties — migrates first. We generate a field-level diff report comparing source values against the corresponding Odoo field values after write. The diff covers standard field mapping, custom field values, owner resolution, parent-partner links, and timestamp preservation. The team reviews the diff and confirms the mapping is correct before the full run is authorized. Any field-level errors or missing custom fields identified in the sample are corrected in the Odoo schema before proceeding.

  5. Execute full migration with delta-pickup cutover window

    The full record set is written to Odoo via XML-RPC API, chunked into batches of 200–500 records per call with checkpoint logging at each batch boundary. After the initial load completes, a delta-pickup window (24–48 hours) captures any Constructor records created or modified during the cutover. A final reconciliation report compares record counts and a sample of field values between Constructor and Odoo. The audit log captures every API write operation with source record ID and timestamp. If reconciliation reveals discrepancies beyond an agreed tolerance, one-click rollback reverts the Odoo environment to its pre-migration state so the team can investigate and re-run.

Platform deep dives

Context on both ends of the pair

Constructor logo

Constructor

Source

Strengths

  • Tightly integrated Sales, Estimating, Accounting, Scheduling, and Payroll modules under one platform.
  • Visual take-off tools and template-driven estimating tailored to residential building workflows.
  • KeyPay-powered payroll with STP Phase 2 compliance for Australian statutory reporting.
  • Cost-plus and progress-claim billing native to the platform — no separate accounting bolt-on needed.
  • Australian-owned with development team in Australia, tuned to ANZ residential-building practice.

Weaknesses

  • Reporting and filter UX is widely cited as weak by G2 reviewers.
  • Uptime has been reported under 90% during some periods.
  • Limited native integration catalog — most connections (Salesforce, ClickHomes, OCR, ELO) require custom build.
  • Regional focus on ANZ residential construction limits fit for builders outside that geography.
  • Public API documentation is thin; integration partners typically engage the vendor for credentials and specs.
Odoo CRM logo

Odoo CRM

Destination

Strengths

  • Modular open-source architecture lets teams start with CRM and add ERP apps as needs grow, all sharing one PostgreSQL database.
  • Free Community edition with no contact limits and full source code access means zero licensing cost for evaluation and small deployments.
  • Drag-and-drop Kanban pipeline with AI lead scoring gives a visual, prioritized view of the sales funnel without requiring custom configuration.
  • Native integrations with email, live chat, SMS, VoIP, WhatsApp, and social media feed all inbound leads into a single unified inbox.
  • Active Odoo Community Association (OCA) maintains dozens of community-maintained modules on GitHub for extended functionality.

Weaknesses

  • Gmail and email integration reliability is a recurring complaint — threads drop and conversations scatter across inboxes, disrupting sales team workflows.
  • Enterprise edition pricing stacks quickly: multiple apps at per-user rates ($25–$50/user/month) plus Odoo.sh hosting costs more than many SMBs anticipate.
  • Setup and configuration complexity increases significantly once custom fields, automation rules, and multiple installed modules are in play.
  • Odoo.sh trial databases run on a version (e.g., 18.3) that is not directly migratable to Odoo.sh, blocking the assisted migration path Odoo advertises.
  • Version upgrades between major Odoo releases (e.g., 17→18) frequently break custom module view definitions and XPath expressions, requiring manual remediation.

Complexity grading

How hard is this migration?

Standard CRM migration. 3 of 8 objects need a mapping; the rest are 1:1.

B

Overall complexity

Standard migration

Derived from compatibility, mapping clarity, API constraints, and data volume across Constructor and Odoo CRM.

  • Object compatibility

    B

    3 of 8 objects need a mapping; the rest are 1:1.

  • Field mapping clarity

    C

    Field mapping is derived from defaults — final spec confirmed during the sample migration.

  • Timeline complexity

    B

    8-object category — typical timelines run 2–7 days end-to-end.

  • API constraints

    B

    Constructor: Not publicly documented — no published rate limits. Typical SaaS limits assumed and confirmed during scoping..

  • Data volume sensitivity

    B

    Constructor doesn't expose a bulk API — REST + parallelization used for high-volume runs.

Estimator

Estimate your Constructor to Odoo CRM migration cost

Rule-based pricing — no per-record fees, no manual quotes. Migrations over 2M records are scoped individually.

Step 1

What are you migrating?

Pick a category, then your source and destination platforms.

Category

FAQ

Frequently asked questions about Constructor to Odoo CRM data migrations

Answers to the questions buyers ask most during Constructor to Odoo CRM migration scoping. Not seeing yours? Book a call.

Can't find your answer?

Walk through your Constructor to Odoo CRM migration with a real engineer — 30 minutes, free, written quote within 24 hours.

Book a free 30 minute consultation

Most Constructor-to-Odoo migrations complete in 48–72 hours of clock time for setups under 50,000 total records. Larger configurations with 500,000+ records or extensive custom-property sets extend to 5–10 days. The longest planning step is the Odoo custom field creation — every Constructor custom property must have a corresponding ir.model.field record before data can be written. Once the Odoo schema is configured and the sample diff is approved, the full load runs in a staged loop with delta-pickup capturing any in-flight changes during the cutover window.

Adjacent paths

Related migrations to explore

Ready when you are

Move from Constructor.
Land in Odoo CRM, intact.

Tell us record counts and timeline. We'll come back with a written quote inside 1 business day — no commitment, no sales pitch.

Accuracy guarantee Rollback included Quote in 1 business day