CRM Automation
Engagement Import Module — How-To Guide & Reference
Overview
This module automates the manual CSV-to-CRM lead intake process. It replaces the multi-step manual process (verify existing lead → create/verify Treatment Center → create/verify Contact → create Opportunity) with a single CSV import wizard.
New Module: menmd_crm_automation
What It Does
- Reads a CSV of marketing engagement events (webinar registrations, badge scans, downloads, website form submissions).
- Matches each row against existing open Opportunities by email, then phone.
- If a match is found, appends the touch to that Opportunity's Campaign History instead of creating a duplicate.
- If no match is found, creates a new Treatment Center record if there isn't one, if there isn't one, it creates a new contact record based on the chosen type, and creates a single new Opportunity.
- Assigns the Opportunity's Salesperson from the Treatment Center's existing Sales Rep, falling back to a Default Owner chosen at import time.
- Tags every newly created Opportunity with the selected Event Type.
- Populates Account Source (Treatment Centers) and Lead Source (Contacts) from the selected UTM Source.
- Applies Webinar Attendee / Tradeshow Attendee tags to both new and existing Contacts, scoped by Record Type.
How to Run an Import
1. Prepare the CSV
Build the file with exactly these column headers, in any order. The importer validates headers strictly and will reject the file if any are missing or misspelled.
Column | Required | Notes |
|---|---|---|
first_name | Yes | Contact's first name. |
last_name | Yes | Contact's last name. |
company | No | Treatment Center name. Leave blank if not applicable. |
Conditional | Primary match key. Either email or phone must be present. | |
phone | Conditional | Fallback match key. Any format is fine & normalized automatically. |
action | Yes | e.g. "Registered", "Attended", "Downloaded", "Contact Form", "Clicked". |
date | No | Defaults to the import date if left blank. |
record_type | Yes | Must be exactly: patient, provider, or support_staff. |
File requirements:
- Header row must match the column names above exactly, lowercase, no spaces.
- One row per person per touch (a person registering and later attending = two rows).
- Save as a true comma-separated .csv file.
- record_type is always required and must be one of the three exact values, the wizard does not currently reject bad values, so accuracy on this column matters.
2. Open the Import Wizard
CRM app → Import Engagements (top navigation menu).
3. Fill Out the Wizard Fields
Field | Purpose |
|---|---|
Event Type | Website Form / Webinar / Download / Conference Badge Scan. Applied as a CRM Tag to every newly created Opportunity in this batch. |
Campaign | utm.campaign = links this batch to a specific marketing initiative. |
Source | utm.source = also used to populate Account Source (Treatment Centers) and Lead Source (Contacts) on newly created records. |
Medium | utm.medium = optional. |
Default Owner (no sales rep) | Required. Salesperson assigned to new Opportunities when the Treatment Center has no existing Sales Rep. |
Webinar Attendee | Optional. Applied to Patient/Provider/Support Staff contacts, new or existing. Leave blank to skip. |
Tradeshow Attendee | Optional. Applied to Provider/Support Staff contacts only (not Patients), new or existing. Leave blank to skip. |
CSV File | The prepared file based on this template. |
4. Process & Review
Click Process Import. The result screen shows:
- Opportunities created
- Engagements appended (matched to an existing open Opportunity)
- Errors = a bad row (e.g. missing both email and phone) is skipped and logged; it does not stop the rest of the batch.
Matching Logic
For each row, the system looks for an existing open Opportunity in this order:
- 1. Email match.
- 2. Phone match.
- 3. Company name match (last resort).
"Open" means: type = opportunity, active = True, and the current stage is not a Won stage. This intentionally does not filter on probability, an early data bug showed that newly created opportunities can have a NULL probability value that silently breaks numeric domain filters, even though it displays as 0.0 in the UI.
Record Creation Rules
Treatment Center (Account)
- Matched by name against existing res.partner records where z_contact_record_type = 'treatment_center'.
- If created new: z_contact_record_type is set to treatment_center, sales_rep is set to the wizard's Default Owner, and z_account_source_custom is set from the selected UTM Source (created in account.source if it doesn't already exist).
Contact
- Matched by email against all res.partner records.
- If created new: z_contact_record_type is set from the CSV's record_type column, linked to the Treatment Center via parent_id, and z_lead_source_custom is set from the selected UTM Source (created in lead.source if it doesn't already exist).
- Webinar/Tradeshow Attendee tags are applied whether the contact is newly created or already existed, tags are added, not overwritten, so prior values are preserved.
Opportunity
- Only created when no existing open Opportunity is found.
- Salesperson (user_id): the Treatment Center's sales_rep if set, otherwise the wizard's Default Owner.
- Tagged with a crm.tag matching the selected Event Type (created if it doesn't already exist).
- A crm.campaign.touch record is created immediately, capturing the first engagement.
Campaign History (Multi-Touch Attribution)
Every engagement, whether it created a new Opportunity or was appended to an existing one, creates a crm.campaign.touch record, visible as a tab on the Opportunity form. Each entry captures: Date, Campaign, Source, Medium, and Action. This preserves full marketing attribution history even though Sales only ever sees one Opportunity per person.