CRM migration

Migrate from Affinity Fieldreach to Odoo CRM

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

Affinity Fieldreach logo

Affinity Fieldreach

Source

Odoo CRM

Destination

Odoo CRM logo

Compatibility

92%

11 of 12

objects map 1:1 between Affinity Fieldreach and Odoo CRM.

Complexity

BStandard

Timeline

48–72 hours

Rollback included Accuracy guarantee Field-level validation

Overview

What this migration involves

Affinity Fieldreach stores relationship data across Persons, Organizations, Deals, and custom fields with a per-user subscription model that becomes expensive as teams grow. Odoo CRM uses crm.lead as a unified model for both raw leads and qualified opportunities, with res.partner serving as the contact and company record simultaneously. We extract Affinity data via their REST API using bearer-token authentication, map Person properties to res.partner fields, Organization records to res.partner companies, and Deals to crm.lead opportunities. Custom fields migrate as Odoo ir.model.fields definitions with type-aware transformations. Affinity automations and workflow rules have no equivalent in Odoo — we export those definitions as JSON for your Odoo developer to rebuild in Odoo's Automations or Server Actions. The migration uses a staged import through Odoo's XML-RPC API with a delta-pickup window capturing any records modified during cutover. Odoo stages translate directly from Affinity deal stages using a value-mapping table, with probability weights re-applied based on Odoo's stage configuration.

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

Affinity Fieldreach logo

Affinity Fieldreach

What's pushing teams away

  • Per-user pricing becomes expensive to scale as the team grows, with many forced premium features that do not justify the cost increase at Advanced and Enterprise tiers.
  • Document management is poor and does not integrate well with external document storage systems, creating friction for deal teams that rely on data rooms.
  • The configurable UI can feel overwhelming for new users due to the number of variables and interaction points across the platform.
  • Limited third-party integrations compared to mainstream CRMs, causing data silos between Affinity and other tools in the investment workflow.

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 Affinity Fieldreach objects map to Odoo CRM

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

Affinity Fieldreach

Person

maps to

Odoo CRM

res.partner

1:1
Fully supported

Affinity Persons map directly to Odoo res.partner records. The partner_type field is set to 'contact' for all migrated Persons. Primary email from Affinity populates email on res.partner, and phone populates phone. Affinity Person IDs are stored in a custom source_id field for traceability.

Affinity Fieldreach

Organization

maps to

Odoo CRM

res.partner

1:1
Fully supported

Affinity Organizations map to res.partner with partner_type set to 'company'. Company names populate the name field. Domain URLs map to website. Additional fields such as industry, employee count, and annual revenue are mapped to their corresponding Odoo partner fields. Parent-child organization hierarchies in Affinity map to parent_id on res.partner, resolved in dependency order during migration.

Affinity Fieldreach

Person-Organization Association

maps to

Odoo CRM

res.partner + res.partner.relation

many:1
Fully supported

Affinity's N:N Person-to-Organization relationships collapse into Odoo's res.partner model where each Person's primary Organization becomes the commercial_partner_id. Secondary affiliations are preserved as a custom relation table until your team decides on a consolidation rule. The migration includes a detailed report of all secondary links, storing source_affinity_id for each affiliation so you can later merge or tag them in Odoo without re-importing data.

Affinity Fieldreach

Deal

maps to

Odoo CRM

crm.lead

1:1
Fully supported

Affinity Deals migrate to Odoo crm.lead as opportunities. The deal name maps to name, amount maps to expected_revenue, and close date maps to date_deadline. Owner resolves by email match to Odoo res.users records. Deal stage translates via a value_map to the appropriate crm.stage, and probability weights are re-applied according to Odoo's stage configuration. Custom fields on deals are created in ir.model.fields before the deal batch loads.

Affinity Fieldreach

Deal Stage

maps to

Odoo CRM

crm.stage

1:1
Fully supported

Affinity deal stages map to Odoo crm.stage records via a value-mapping table. Each Affinity stage name gets a corresponding Odoo stage_id within the target team's stage_ids. Stage sequence order and probability weights are preserved from Affinity's stage configuration. After migration, you can adjust stage names, add new stages, or reassign probability weights directly in Odoo's pipeline view without affecting the underlying data.

Affinity Fieldreach

Activity (Call/Email/Meeting)

maps to

Odoo CRM

mail.activity

1:1
Fully supported

Affinity activity records (calls, emails, meetings) migrate as Odoo mail.activity entries linked to the corresponding crm.lead or res.partner via res_model and res_id. Activity type, summary, and date are preserved; owner maps by email to res.users. If an activity has an associated note or attachment, those are migrated separately as mail.message or ir.attachment records linked to the same res_model and res_id, ensuring a complete activity history in Odoo.

Affinity Fieldreach

Note

maps to

Odoo CRM

mail.message

1:1
Fully supported

Affinity notes attached to Persons, Organizations, or Deals become Odoo mail.message records with message_type='comment'. Body content preserves plain text; rich-text notes are converted to HTML for Odoo's message rendering. The note author is resolved by email to a res.partner, and any file attachments are stored as ir.attachment records linked to the same message, keeping the full note context intact.

Affinity Fieldreach

Custom Field (Person)

maps to

Odoo CRM

ir.model.fields + res.partner

1:1
Fully supported

Affinity custom fields on Persons require Odoo custom field creation via ir.model.fields before data loads. Char fields map directly; selection fields require value_mapping; multi-select fields need dedicated relation tables or serialized storage. We preserve the original Affinity field label as the Odoo field name and generate a unique technical name (e.g., x_affinity_cf_<id>) to avoid conflicts. Field visibility can be restricted to specific user groups if needed.

Affinity Fieldreach

Custom Field (Organization)

maps to

Odoo CRM

ir.model.fields + res.partner

1:1
Fully supported

Organization custom fields migrate similarly to Person custom fields. Odoo custom fields are created with the same label as the Affinity fields, and a technical name (e.g., x_affinity_org_<id>) is generated to avoid conflicts. Field type determines the transformation — char fields map directly, selection fields use value_mapping, and multi-select fields are stored via dedicated relation tables or serialized fields. Definitions are created in ir.model.fields before the organization batch loads.

Affinity Fieldreach

Custom Field (Deal)

maps to

Odoo CRM

ir.model.fields + crm.lead

1:1
Fully supported

Deal-level custom fields in Affinity map to custom columns on crm.lead in Odoo. The field type from Affinity (text, number, date, picklist) determines the Odoo field type (char, float, date, selection) and any required value_mapping. Multi-select fields are stored via dedicated many2many tables or serialized JSON in a char field. Custom columns are created in ir.model.fields before the deal batch is imported, and field help text is copied from Affinity.

Affinity Fieldreach

Attachment

maps to

Odoo CRM

ir.attachment

1:1
Fully supported

Affinity file attachments download from Affinity's storage URLs and re-upload to Odoo via ir.attachment create() calls. The original filename, mimetype, and create date are preserved. Attachments link to res.partner or crm.lead via res_model and res_id. A backup of the original Affinity URL is stored in a custom field for reference, and large files are saved as bytea in PostgreSQL or on the filesystem depending on your Odoo configuration.

Affinity Fieldreach

User/Owner

maps to

Odoo CRM

res.users

1:1
Fully supported

Affinity owner IDs resolve by email match against Odoo res.users. Unmatched owners are flagged before migration — your Odoo admin either creates the user or assigns records to a fallback owner before the migration commits. For traceability, the original Affinity owner identifier is stored in a custom source_owner_id field on each record. If many owners are missing, a user-provisioning script can be run before the migration to reduce fallback assignments.

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.

Affinity Fieldreach logo

Affinity Fieldreach gotchas

High

v2 API is not at feature parity with v1

Medium

Rate limits constrain bulk export windows

Medium

Custom fields silently truncated in third-party integrations

Low

Choice field types are immutable after creation

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

  • Person-Organization N:N collapse requires admin decision

    Affinity allows a Person to关联 multiple Organizations simultaneously. Odoo res.partner has a single commercial_partner_id for company linkage, so each contact can reference only one primary organization. During migration we preserve all affiliations in a custom relation table, but your team must decide whether to collapse secondary affiliations into contact tags or keep them as a custom relation for future consolidation. This choice affects downstream reporting and segmentation in Odoo. The migration plan surfaces the count of multi-affiliation Persons before committing, giving your admin time to define tagging rules or accept the custom relation approach before data goes live.

  • Custom fields require Odoo field creation before data loads

    Affinity custom fields exist at the org level and are referenced by field ID in API responses. Odoo requires custom fields to be defined in ir.model.fields before records with those values can load. We create the fields via XML-RPC before importing data, but field types must match — Affinity multi-select pick-lists need either serialized storage or a dedicated many2many relation table in Odoo, and the choice affects downstream reporting. Additionally, field technical names must be unique across the Odoo database, and visibility can be restricted per group, so your admin should confirm the intended access rights before migration commits.

  • Odoo API requires database name and UID at every call

    Unlike Affinity's single bearer-token endpoint, Odoo's XML-RPC interface at /xmlrpc/2/object requires database name, user ID (uid), and password for every request. We handle authentication sequencing — logging in to receive a uid before each batch write — but Odoo sessions time out after extended idle periods, which we manage with connection pooling to prevent mid-migration auth failures. In addition, we refresh the uid automatically if a session expires mid-batch, and we log each authentication attempt to facilitate debugging. If Odoo's session limit is reached due to concurrent API usage, the migration service queues the request and retries after a backoff, ensuring that large record sets can be processed without intervention.

  • Affinity automations have no Odoo equivalent

    Affinity workflow rules and automations do not migrate. They require rebuilding in Odoo using Automations (base.automation) or Server Actions. We export the full automation definitions as a JSON reference document, but the rebuild is a manual step your Odoo developer or admin must complete after data lands. We flag which records were affected by Affinity automations so the rebuild can prioritize the highest-volume workflows. During the rebuild, each automation's trigger (e.g., field change, date condition) must be mapped to the equivalent Odoo trigger, and any email templates or webhook actions need to be recreated as Odoo mail templates or server actions. Testing each rebuilt automation before activation is recommended.

  • Activity owners must resolve to existing Odoo users

    Affinity activity records store owner_id, which may reference users not yet provisioned in Odoo. If the owner email has no matching res.users record, the activity is flagged and loaded under a migration-service system user. Your admin must either provision those users before migration or accept that historical activities for unprovisioned owners appear under a system account rather than the original owner. To preserve auditability, we store the original owner identifier in a custom source_owner_id field on each migrated activity. After provisioning the missing users, a reconciliation script can update the user_id and clear the fallback flag, restoring proper attribution without re‑importing data.

Migration approach

Six steps for a successful Affinity Fieldreach to Odoo CRM data migration

  1. Extract Affinity data via REST API

    FlitStack authenticates to Affinity's REST API using bearer-token credentials from your Affinity Settings. We paginate through Persons, Organizations, Deals, Activities, Notes, and custom field definitions in dependency order — custom field schemas load first so downstream record extraction can resolve field IDs to names. API rate limits are managed with a backoff strategy, and any 429 responses trigger automatic retry after the reset window.

  2. Create Odoo custom fields and stage mappings

    Before any data loads, FlitStack provisions Odoo custom fields via XML-RPC calls to ir.model.fields for each Affinity custom property. Custom field types are inferred from Affinity's field type metadata (char, selection, multi-select) and mapped to Odoo's field type equivalents. Simultaneously, we create crm.stage records for each Affinity deal stage and build the value_map table linking Affinity stage IDs to Odoo stage_id integers.

  3. Migrate Organizations then Persons then Deals

    Odoo's foreign-key model requires Organizations (res.partner with partner_type=company) to load before Persons can link to them. We sequence the migration: Organizations first with parent_id resolution for hierarchy, then Persons with commercial_partner_id set to their primary Organization, then Deals (crm.lead) with partner_id pointing to the Organization and stage_id resolved via the value_map table. Activity records load last, resolving res_model and res_id via the source_affinity_id lookups created during earlier stages.

  4. Run sample migration with field-level diff

    A representative slice — typically 100–500 records across Persons, Organizations, Deals, and Activities — migrates first. We generate a field-level diff showing source values from Affinity against the loaded values in Odoo. Your team verifies stage mapping correctness, custom field population, and owner resolution before the full run commits. This sample run also validates API authentication stability and batch-write throughput for your Odoo instance.

  5. Cut over with delta-pickup and audit log

    The full migration commits to your production Odoo database. A 24–48 hour delta-pickup window captures any records created or modified in Affinity during the cutover. Every write operation is logged in an audit table including source Affinity ID, destination Odoo record ID, field changed, old value, and new value. One-click rollback reverts all migrated records if reconciliation against the audit log fails. After rollback window closes, the migration is considered complete and your team operates in Odoo.

Platform deep dives

Context on both ends of the pair

Affinity Fieldreach logo

Affinity Fieldreach

Source

Strengths

  • Purpose-built for deal sourcing and relationship tracking in investment workflows.
  • Pipeline management with stage customization aligns directly with PE/VC fund cycle needs.
  • List-based tracking enables teams to group contacts by fund, portfolio company, or deal stage.
  • Per-user pricing is transparent and predictable across Essential, Advanced, and Enterprise tiers.
  • API access allows programmatic data extraction and integration with portfolio reporting tools.

Weaknesses

  • Document management features lag behind mainstream CRM platforms.
  • Expensive to scale beyond 20–30 users due to per-user pricing model.
  • Complex and overwhelming UI for new team members without dedicated onboarding.
  • Limited third-party integrations compared to Salesforce or HubSpot.
  • Premium features at Advanced and Enterprise tiers include significant cost uplift for commoditized capabilities.
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. 1 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 Affinity Fieldreach and Odoo CRM.

  • Object compatibility

    B

    1 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

    Affinity Fieldreach: Per-minute request limit + per-month account cap + concurrent request limit; exact thresholds vary by plan.

  • Data volume sensitivity

    B

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

Estimator

Estimate your Affinity Fieldreach 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 Affinity Fieldreach to Odoo CRM data migrations

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

Can't find your answer?

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

Book a free 30 minute consultation

Most Affinity-to-Odoo migrations complete in 48–72 hours of clock time for under 50,000 records. The longest phase is usually creating Odoo custom fields and stage mappings before data loads — this schema setup runs concurrently with the sample migration. Larger setups with 500k+ records or complex custom-field hierarchies extend to 5–7 days. Odoo's XML-RPC API adds per-call overhead compared to bulk-load methods, which we mitigate with connection pooling and batched writes.

Adjacent paths

Related migrations to explore

Ready when you are

Move from Affinity Fieldreach.
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