CRM migration

Migrate from Practice by Numbers to Odoo CRM

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

Practice by Numbers logo

Practice by Numbers

Source

Odoo CRM

Destination

Odoo CRM logo

Compatibility

90%

9 of 10

objects map 1:1 between Practice by Numbers and Odoo CRM.

Complexity

BStandard

Timeline

3–5 days

Rollback included Accuracy guarantee Field-level validation

Overview

What this migration involves

Practice by Numbers stores dental-practice data as patients, providers, appointments, treatments, and insurance records with a reporting layer built for dental KPIs. Odoo CRM uses crm.lead for leads and opportunities, res.partner for contacts and companies, and ir.model.data for custom fields — a fundamentally different relational model. We extract from Practice by Numbers via its reporting export and direct API where available, transform dental-record types into Odoo-compatible partner and lead records, and land them in the correct crm.lead stages and res.partner addresses. Treatment plans and insurance data that have no direct Odoo equivalent migrate as custom fields on res.partner and crm.lead, flagged for manual review. Our migration does not move automated reminders, patient-communication sequences, or goal-management rules — those live in Practice by Numbers and must be rebuilt as Odoo自动化规则 (automation rules) post-migration. A sample migration with field-level diff runs first; a 24–48-hour delta pickup window captures any records modified during cutover.

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

Practice by Numbers logo

Practice by Numbers

What's pushing teams away

  • Limited public API documentation makes automated data extraction difficult, forcing practices to rely on manual CSV exports which restrict field selection and historical depth.
  • No free tier or low-cost entry point means the full feature set requires a significant commitment before the practice can validate fit with their specific workflow.
  • The breadth of features creates a steep onboarding curve, and some practices report that staff adoption lags during the first months after implementation.

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 Practice by Numbers objects map to Odoo CRM

Each row shows how a Practice by Numbers 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.

Practice by Numbers

Patient

maps to

Odoo CRM

res.partner

1:1
Fully supported

Practice by Numbers patient records map directly to Odoo res.partner. The patient's full name splits into firstname and lastname on res.partner. Email, phone, and address fields migrate one-to-one. The original Practice by Numbers patient ID is stored as x_source_patient_id for delta-run de-duplication.

Practice by Numbers

Provider

maps to

Odoo CRM

res.users

1:1
Fully supported

Practice by Numbers providers (doctors, hygienists) are staff members, not contacts. We resolve each provider against Odoo res.users by email match. Providers without Odoo user accounts are flagged and can be invited before migration or assigned to a fallback user. Provider specialty (GP vs. specialist) maps to a custom x_provider_specialty field.

Practice by Numbers

Appointment

maps to

Odoo CRM

crm.activity

1:1
Fully supported

Each Practice by Numbers appointment becomes an Odoo crm.activity record linked to the crm.lead that owns the patient. The activity type (checkup, cleaning, procedure) maps to an Odoo activity_type_id; the appointment date and duration become the crm.activity date_deadline and duration fields. Cancelled appointments migrate with a 'cancelled' state flag.

Practice by Numbers

Treatment Plan

maps to

Odoo CRM

sale.order

1:1
Fully supported

Proposed treatments in Practice by Numbers translate to Odoo sale.order lines. Each treatment item becomes a sale.order.line with the procedure description as name, fee as price_unit, and the responsible provider as user_id. Confirmed treatment plans with patient acceptance migrate as sale.order records in the 'sale' state; unconfirmed plans remain as draft quotations.

Practice by Numbers

Insurance Record

maps to

Odoo CRM

res.partner (custom fields)

1:1
Fully supported

Insurance carrier name, group number, policy number, subscriber ID, and coverage percentage have no native Odoo res.partner fields. These migrate as x_insurance_carrier, x_group_number, x_policy_number, x_subscriber_id, and x_coverage_pct custom fields on res.partner. If the practice uses secondary insurance, a second set of fields is created or a related x_insurance_partner_id many2one is added.

Practice by Numbers

Recall / Reactivation

maps to

Odoo CRM

crm.lead + mail.activity

many:1
Fully supported

Practice by Numbers recall dates (6-month hygiene recall, annual checkup) merge into Odoo crm.lead records: one lead per recall type, with the recall date stored as x_recall_date and a scheduled mail.activity set for 7 days before that date. This gives Odoo's native reminder system rather than a separate recall table.

Practice by Numbers

Payment / Ledger

maps to

Odoo CRM

account.move

1:1
Fully supported

Practice by Numbers payment history is billing data that lives in its own ledger. Odoo account.move records are accounting entries tied to the Odoo accounting module, which may not be installed. We preserve the payment ledger as a custom x_payment_history JSON field on res.partner for reference — the accounting module handles future payments post-migration.

Practice by Numbers

Goal / KPI Target

maps to

Odoo CRM

Custom x_goal target fields on crm.lead

1:1
Fully supported

Practice by Numbers goal management records per-provider production, acceptance rate, and new‑patient targets. Each target maps to a custom float field on res.users: x_monthly_production_target, x_acceptance_rate_target, and x_new_patient_target. These fields enable Odoo’s native dashboard, pivot, and graph views to show team and individual performance against the same metrics. Default values preserve the original goal figures for each provider.

Practice by Numbers

Communication Log

maps to

Odoo CRM

mail.message

1:1
Fully supported

Patient communication history (appointment reminders, confirmations, recalls) in Practice by Numbers migrates as mail.message records linked to res.partner. The original message content, send date, and channel (SMS, email) are preserved. Odoo's mail_thread on res.partner surfaces these messages in the chatter sidebar.

Practice by Numbers

Custom Dental Properties

maps to

Odoo CRM

ir.model.fields (x_* custom fields)

1:1
Fully supported

Any custom properties defined in Practice by Numbers (e.g., referring dentist, preferred appointment time, treatment preferences) migrate as Odoo x_ prefixed custom fields on res.partner or crm.lead. Field type is inferred from the source value type: text strings become char, numeric values become float or integer, date values become date.

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.

Practice by Numbers logo

Practice by Numbers gotchas

High

No publicly documented API for automated migration

High

Dental EHR data is inherently messy during extraction

Medium

Goal management metrics require explicit field mapping

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

  • Practice by Numbers patient records lack a native 'lead vs. contact' distinction

    Practice by Numbers treats every patient as a unified record regardless of where they are in the funnel — a new patient lead and an existing treatment patient use the same object. Odoo separates crm.lead (unqualified prospects) from res.partner (qualified contacts with whom you have a relationship). FlitStack AI routes each patient based on the most recent appointment status: patients with a completed appointment land as res.partner, and patients with only scheduled or inquiry-stage appointments land as crm.lead records. A custom x_source_record_type field flags the original Practice by Numbers classification so your team can re-segment in Odoo.

  • Odoo crm.lead type field must be set before custom field visibility works correctly

    Odoo's crm.lead record has a type field set to 'lead' or 'opportunity', and many custom field visibility rules in Odoo Studio depend on this value. If a custom field is defined on crm.lead but the record's type is unset or null, Odoo may suppress the field in list and form views even after migration. FlitStack AI explicitly sets type='lead' for all migrated patient records and type='opportunity' for treatment plans that represent active sales, ensuring all x_ prefixed fields render correctly in Odoo's kanban and form views.

  • Recall scheduling requires Odoo mail.activity creation — not just date fields

    Practice by Numbers tracks recall dates (e.g., 6-month hygiene recall) as date fields on the patient record and sends reminders through its own communication engine. In Odoo, a date field alone does not generate reminders. FlitStack AI creates a scheduled mail.activity linked to each crm.lead with activity_type_id='callback', date_deadline set to the recall date minus 7 days, and the note field containing the recall type. If the Odoo Discuss module is not installed, the activity still appears in the CRM activity kanban but no email fires automatically — your admin installs the mail module or configures an Odoo automation rule to send the actual reminder.

  • Provider-to-user resolution creates inactive Odoo users if not pre-created

    Odoo requires a res.users record before a crm.activity or crm.lead can be assigned to a user_id. If your Practice by Numbers account has providers (doctors, hygienists) that do not yet have Odoo logins, FlitStack AI flags them before migration and either creates placeholder inactive users or assigns their records to a fallback sales team. The warning appears in the pre-migration diff report so your Odoo admin can invite the team before the go-live date.

  • Insurance sub-objects may require a second res.partner record for dual coverage

    Practice by Numbers supports primary and secondary insurance on a single patient record. Odoo res.partner has a native property field for the commercial partner (company) and a child_ids one2many for contacts, but no native many2one for an insurance carrier partner. For secondary insurance, FlitStack AI either creates a dedicated res.partner record for the insurance company (storing carrier details in the standard address/name fields) and links it via a custom x_secondary_insurer_id field, or stores the secondary insurance as additional x_ fields on the patient record — your admin chooses the approach before migration runs.

Migration approach

Six steps for a successful Practice by Numbers to Odoo CRM data migration

  1. Extract Practice by Numbers data via report exports and API

    FlitStack AI connects to Practice by Numbers using scoped read access (report exports for bulk patient and appointment data, API where available for real-time fields). We extract all patients, providers, appointments, treatment plans, insurance records, and communication logs. A data audit report identifies duplicate emails, missing required fields, and unmapped custom properties before any transformation logic runs. The source system remains fully operational during this read-only phase.

  2. Set up Odoo schema: custom fields, activity types, and user accounts

    Before data lands, FlitStack AI generates an Odoo setup plan listing every x_ custom field to create (x_insurance_carrier, x_recall_date, x_provider_specialty, etc.), every crm.activity.type record to create per appointment type, and every res.users record needed for provider-to-user resolution. Your Odoo admin creates the fields and invites providers as users. This step runs in parallel with the source data extract and prevents validation errors during the import phase.

  3. Resolve owners and run field-level mapping validation

    Every provider_id in Practice by Numbers is matched against Odoo res.users by email. Unmatched providers appear in a resolution report with recommended fallback assignments. Simultaneously, FlitStack AI validates the field mapping plan — checking that date formats, pick-list values, and numeric ranges conform to Odoo's field type constraints. Any mapping that would cause an Odoo validation error is flagged with a recommended fix before migration commits any data.

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

    A representative slice of 100–500 records — spanning patients, appointments, treatment plans, and at least one recall record — migrates to Odoo first. FlitStack AI generates a field-level diff comparing each source field value against the destination field value, with any transformation noted. Your team reviews the diff in a shared report and confirms the mapping is correct before FlitStack AI runs the full migration. This step is the last chance to adjust mapping logic without committing the full dataset.

  5. Execute full migration with delta-pickup and audit log

    The full migration runs in Odoo using batched writes via the XML-RPC API, respecting Odoo's transaction boundaries. A 24–48-hour delta-pickup window opens immediately after the full run, capturing any new patient records or appointment updates made in Practice by Numbers during the cutover. FlitStack AI generates a complete audit log of every record written, every field populated, and every record that failed validation with the reason. One-click rollback reverts all migrated records if reconciliation finds unexpected gaps.

Platform deep dives

Context on both ends of the pair

Practice by Numbers logo

Practice by Numbers

Source

Strengths

  • Bi-directional integration with major dental PMSs (Open Dental 15.4+, Dentrix, Dentrix Ascend, EagleSoft, Practice-Web) — PbN writes SMS, email, call and note activity back into the PMS CommLog so the PMS remains the system of record.
  • Dentist-founded product with a 9.8/10 G2 support rating and 99.99% advertised uptime — reviewers consistently call out responsive support and quick feature delivery.
  • Real-time Practice IQ dashboards cover production, collections, case acceptance, new-patient, hygiene reappointment and other dental KPIs that horizontal BI tools do not pre-build.
  • PbN Voice native phone system (call tracking, recording, analytics) plus payments, digital forms and insurance verification consolidate vendors small practices would otherwise stitch together.
  • Modular plan structure lets practices add Voice, Payments or specific modules incrementally rather than paying for everything in tier 1.

Weaknesses

  • Only the Core plan ($249/month) has publicly listed pricing — higher tiers (Flow, Scale, Thrive) require sales contact, complicating self-serve evaluation.
  • Reports are not customisable enough for some practices — granular per-practice metric configuration often requires support involvement.
  • Single-location practices report PbN can feel expensive relative to features they actually use — pricing is more competitive at multi-location and DSO scale.
  • Some digital-form and online-scheduling flows have reliability gaps — reviewers cite forms occasionally failing to send and patients struggling to open them.
  • PbN is a layer on top of the PMS, not the PMS itself — practices migrating need to plan PMS-side data extraction (Open Dental, Dentrix) in parallel.
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. All 8 core objects map 1:1 between Practice by Numbers and Odoo CRM.

B

Overall complexity

Standard migration

Derived from compatibility, mapping clarity, API constraints, and data volume across Practice by Numbers and Odoo CRM.

  • Object compatibility

    A

    All 8 core objects map 1:1 between Practice by Numbers and Odoo CRM.

  • 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

    Practice by Numbers: Not publicly documented.

  • Data volume sensitivity

    B

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

Estimator

Estimate your Practice by Numbers 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 Practice by Numbers to Odoo CRM data migrations

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

Can't find your answer?

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

Book a free 30 minute consultation

Most migrations complete in 3–5 days of clock time for under 25,000 patient records. Larger practices with 100,000+ records across appointments, treatment plans, and recall scheduling extend to 7–14 days. The longest phase is the Odoo schema setup (creating x_ custom fields, activity types, and resolving provider-to-user accounts), which can take 1–3 days before data moves. The actual import runs in hours; the planning and validation steps run in days.

Adjacent paths

Related migrations to explore

Ready when you are

Move from Practice by Numbers.
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