Стратегия переезда — что мигрируем, а что оставляем в архиве
Меня зовут Евгений Семёнов, я технический директор ITfresh. Мы обслуживаем юридические лица до 50 рабочих мест в Москве, держим собственные серверы в дата-центре МТС и с 2011 года переносим клиентам данные из одной системы в другую — с облаков на коробки, с коробок на облака и обратно. Так вот: самый частый вопрос, который мне задают про Odoo, — не «как её поставить». Поставить — дело техники, про это у меня есть отдельная статья. Настоящий страх у собственника другой: «У меня в старой CRM пять лет истории. Я не хочу это потерять». Эта статья — методичка ровно про то, как переехать и ничего не потерять.
Первое, что я всегда проговариваю на старте: миграция — это не «перелить всё подряд». База, которая копилась пять лет, содержит горы мусора: дубли, брошенные сделки, контакты уволившихся сотрудников контрагентов, тестовые записи менеджеров. Тащить это в новую чистую систему — значит на первый же день загадить её тем самым хламом, от которого вы и хотели уйти. Поэтому переезд начинается не с выгрузки, а с решения: что везём, а что оставляем в архиве.
Матрица решений: что переносим
Вот как мы раскладываем сущности старой CRM по категориям. Эту таблицу я показываю клиенту на первой встрече, и мы вместе проходим по строкам.
| Сущность | Решение | Почему так |
|---|---|---|
| Контакты и компании | ✅ Переносим всегда | Это ядро базы, актив компании. Без него переезд бессмыслен |
| Открытые сделки | ✅ Переносим всегда | Это деньги в работе прямо сейчас, менеджеры продолжат их вести |
| Закрытые сделки за последние 1–2 года | ✅ Переносим | Нужны для аналитики, скоринга и истории по клиенту |
| Закрытые сделки старше 2 лет | ⚠️ Спорно — в архив | Наш подход: отдельная выгрузка в CSV/Excel, а не в боевую базу |
| Переписка и файлы | ⚠️ Селективно | Только по живым клиентам и открытым сделкам, остальное — балласт |
| Задачи и напоминания | ❌ Не мигрируем | Пересоздаём в Odoo вручную — старые дедлайны уже неактуальны |
Отдельно остановлюсь на спорной строке — закрытых сделках старше двух лет. Здесь у меня твёрдая позиция, выстраданная на нескольких проектах. Тащить в боевую Odoo десятки тысяч старых закрытых сделок «на всякий случай» — плохая идея по трём причинам: они раздувают базу, замедляют поиск и отчёты, и, главное, засоряют статистику для предиктивного скоринга устаревшими паттернами. Наш подход — выгрузить весь исторический архив в отдельный CSV/Excel-файл и положить его на файловое хранилище. Данные не потеряны, они лежат в понятном виде, и в тот редкий раз, когда бухгалтеру или юристу понадобится сделка трёхлетней давности, её достанут из архива. А боевая система остаётся чистой.
Про задачи и напоминания тоже поясню, почему их нет смысла мигрировать. Напоминание «перезвонить Иванову 15 марта» из старой системы к моменту переезда либо уже просрочено, либо неактуально. Модель активностей в Odoo устроена иначе, чем в amoCRM или Bitrix24, и попытка перенести старые задачи один в один порождает кашу. Правильнее — при переезде менеджер открывает свои живые сделки и заново планирует по ним следующий шаг уже в Odoo. Это заодно и хорошая ревизия: висящие мёртвые задачи отсеиваются сами собой.
Выгрузка из источников: amoCRM, Bitrix24 и Excel
Когда решили, что везём, — начинаем выгружать. У каждого источника свои особенности и свои грабли. Разберу три самых частых: amoCRM, Bitrix24 и «таблички» (Excel/Google Sheets). Сразу оговорюсь: почти везде есть кнопка «Экспорт в CSV», но полагаться только на неё нельзя — ниже объясню почему.
amoCRM — экспорт через REST API v4
У amoCRM есть штатный экспорт в CSV из интерфейса, и для контактов он более-менее работает. Но стандартный CSV регулярно теряет кастомные поля — те самые дополнительные поля, которые вы годами настраивали под свой бизнес: «источник заявки», «тип клиента», ИНН, второй телефон. А именно в них часто и лежит самое ценное. Поэтому серьёзную выгрузку мы делаем через REST API v4.
Ключевые технические моменты работы с API amoCRM, которые надо держать в голове:
- Авторизация — OAuth 2.0. Нужен долгоживущий токен или связка access/refresh. Токен передаётся в заголовке каждого запроса.
- Лимит запросов — около 7 запросов в секунду. Превысите — получите ответ 429 и временную блокировку. Поэтому выгрузку делаем с паузами, не в лоб.
- Курсорная пагинация. Данные отдаются страницами; за следующую порцию отвечает ссылка
_links.nextв ответе. Идём по курсору, пока он не закончится, — так надёжнее, чем считать номера страниц. - Связанные сущности запрашиваются через параметр
with. Например, чтобы к сделке подтянуть контакты и компанию, передаёмwith=contacts. Иначе получите голые сделки без привязок.
Забирать через API нужно все нужные сущности: контакты (/api/v4/contacts), компании (/api/v4/companies), сделки (/api/v4/leads — да, в amoCRM сделки исторически называются leads) и справочник кастомных полей (/api/v4/leads/custom_fields), чтобы понимать, что означает каждое числовое поле в выгрузке. Всё это складываем в промежуточные JSON-файлы — на них мы потом будем строить маппинг.
Bitrix24 — вебхуки и коварные multifield-поля
С Bitrix24 работаем через входящие вебхуки — это проще OAuth: в настройках создаёте вебхук с правами на CRM и получаете URL с токеном, к которому дёргаете REST-методы. Основные методы для выгрузки:
| Метод | Что выгружает |
|---|---|
crm.contact.list | Контакты (физлица) |
crm.company.list | Компании |
crm.lead.list | Лиды (необработанные обращения) |
crm.deal.list | Сделки |
Методы *.list отдают данные страницами по 50 записей — листаем через параметр start (start=0, 50, 100…), пока не переберём всё. И вот здесь — главный подводный камень Bitrix24, на котором спотыкаются почти все.
[{"VALUE":"+79031234567","VALUE_TYPE":"WORK"}, ...]. У одного контакта может быть три телефона и два адреса. Если наивно выгрузить поле PHONE как текст, вы получите пустоту или служебный мусор. Нужно разбирать массив: брать VALUE из каждого элемента, а тип (WORK/MOBILE) — учитывать при маппинге. Это самая частая причина, почему после «миграции по-быстрому» у половины контактов пропадают телефоны.Ещё одна деталь: в crm.deal.list по умолчанию возвращается не полный набор полей. Чтобы получить кастомные поля (они называются UF_CRM_*), их надо явно перечислить в параметре select либо запросить select: ["*", "UF_*"]. Справочник пользовательских полей отдаёт метод crm.deal.userfield.list — без него вы не поймёте, что означает UF_CRM_1612345678.
Excel и Google Sheets — нормализация руками
Отдельная категория клиентов ведёт продажи в таблицах. Данные там «человеческие», то есть с точки зрения импорта — хаотичные. Перед загрузкой в Odoo такую таблицу надо нормализовать, и это ручная работа, которую нельзя пропустить:
- Телефоны — к единому формату +7. В таблицах телефоны записаны как попало: 8 (903) 729-62-41, 89037296241, +7 903 729 62 41, добавочные через запятую. Приводим всё к виду
+79037296241, добавочные выносим в отдельное поле. - ИНН — только как текст! Это классическая ловушка Excel. ИНН, начинающийся с нуля (а такие бывают у ряда регионов), Excel превратит в число и съест ведущий ноль: 0277… станет 277…. Десятизначный ИНН может уехать в экспоненциальную запись. Столбец ИНН обязательно форматируем как текст до любых манипуляций.
- Разделение ФИО. Если в таблице одна колонка «Иванов Иван Иванович», а в Odoo вы хотите отдельно фамилию, имя и отчество или хотя бы корректное отображение, — ФИО придётся разбить. Автоматом это делается формулами, но результат надо глазами проверить: двойные фамилии и отсутствующие отчества ломают простое деление по пробелам.
- Единые справочники. «Москва», «г. Москва», «москва», «МСК» в глазах импортёра — четыре разных города. Прогоните столбцы-категории через фильтр уникальных значений и причешите разнобой до импорта.
Именно на этапе выгрузки закладывается качество всего переезда. Грязные данные на входе — грязная система на выходе, никакая Odoo это за вас не исправит.
Маппинг данных на модель Odoo
Данные выгружены. Теперь — самая интеллектуальная часть переезда: маппинг, то есть сопоставление полей старой системы полям Odoo. Чтобы его сделать, надо понимать, как устроена модель данных Odoo. Разберу три ключевые модели, с которыми имеем дело при миграции CRM.
res.partner — контакты и компании в одной модели
Первое, что удивляет пришедших из amoCRM или Bitrix24: в Odoo и компании, и физлица-контакты живут в одной модели — res.partner. Различает их поле is_company (true — это организация, false — человек). А иерархия «сотрудник работает в компании» задаётся полем parent_id: у карточки человека в parent_id стоит ссылка на карточку его компании. Так в Odoo выстраивается дерево: организация, а под ней — её контактные лица.
Это принципиально иначе, чем «контакты» и «компании» как отдельные таблицы в Bitrix24, и при маппинге надо это учитывать: компанию из старой системы мы создаём как res.partner с is_company=true, её сотрудников — как res.partner с is_company=false и parent_id, указывающим на эту компанию.
crm.lead — и лиды, и сделки
Вторая особенность: в Odoo лиды и сделки — это тоже одна модель, crm.lead. Различает их поле type: значение lead — это сырой лид, opportunity — квалифицированная сделка в воронке. Стадия сделки задаётся полем stage_id, которое ссылается на модель crm.stage — справочник стадий вашей воронки.
Значит, перед импортом сделок надо сначала настроить воронку в Odoo — создать стадии crm.stage, соответствующие вашему процессу продаж, — и только потом сопоставлять старые статусы сделок этим стадиям.
Таблица соответствия amoCRM → Odoo
Вот типовой маппинг, от которого мы отталкиваемся при переезде с amoCRM. Bitrix24 ложится по той же логике, отличаются лишь имена исходных полей.
| Поле в amoCRM | Модель и поле в Odoo | Комментарий |
|---|---|---|
| Компания (company) | res.partner, is_company=true | Организация как отдельная карточка |
| Контакт (contact) | res.partner, is_company=false, parent_id | Человек, привязанный к компании |
| Название сделки | crm.lead, name | type=opportunity |
| Бюджет сделки | crm.lead, expected_revenue | Ожидаемая выручка |
| Статус / этап | crm.lead, stage_id → crm.stage | Требует заранее настроенной воронки |
| Ответственный | crm.lead, user_id → res.users | Менеджера надо предварительно завести в Odoo |
| Телефон / e-mail | res.partner, phone / email | Приводим к единому формату |
| ИНН (кастомное поле) | res.partner, vat | В Odoo под ИНН есть штатное поле vat |
| Источник заявки (кастом) | crm.lead, source_id / medium_id | UTM-справочники Odoo |
| Прочие кастомные поля | Новое поле ir.model.fields | Создаём под каждое своё поле |
Кастомные поля без единой строчки кода
Что делать с полями, которым нет штатного аналога в Odoo, — всеми этими «Как узнали о нас», «Категория клиента», «Номер договора»? Их создают прямо через интерфейс, без программирования: Settings → включаем режим разработчика → Technical → Database Structure → Fields (модель ir.model.fields). Выбираете модель (например, crm.lead), задаёте имя поля, тип (текст, число, дата, список выбора, ссылка) — и поле появляется в карточке. Никакого кода. Под каждое кастомное поле старой системы, которое мы решили везти, заводим соответствующее поле в Odoo до импорта.
amo_contact_10345, где 10345 — ID контакта в amoCRM. Что это даёт: если вы запустите импорт того же файла повторно, Odoo по External ID поймёт, что запись уже есть, и не создаст дубль, а обновит существующую. Это превращает импорт из «одноразового выстрела, который страшно повторять» в управляемый повторяемый процесс: залили, увидели ошибку в данных, поправили исходник, залили снова — дублей не будет. Без External ID любой повторный импорт удваивает базу. Продумайте схему External ID до первой загрузки.Импорт — два пути: штатный CSV-импортёр и XML-RPC
Маппинг готов, поля заведены, External ID продуманы. Пора заливать. В Odoo есть два принципиально разных способа импорта, и выбор между ними зависит от объёма и сложности данных.
Путь первый: штатный CSV-импортёр
У каждой модели в Odoo есть кнопка Import (в режиме списка). Вы загружаете CSV или XLSX, и Odoo показывает интерфейс сопоставления колонок: слева — колонки вашего файла, справа — поля модели, и вы связываете их выпадающими списками. Odoo умеет угадывать соответствия по названиям, а связи между записями (тот же parent_id или stage_id) подтягивает по External ID или по имени.
Плюсы штатного импортёра: не нужен программист, есть тестовый прогон (кнопка Test — Odoo проверит файл и покажет ошибки, ничего не записав), понятные сообщения об ошибках построчно. Минусы: на больших файлах он медленный и капризный.
Путь второй: XML-RPC-скрипт на Python
Для крупных баз и сложной логики (дедупликация на лету, обработка multifield, связывание сущностей) мы пишем скрипт на Python, который заливает данные через External API Odoo. В Odoo 19 это два эндпоинта XML-RPC: xmlrpc/2/common (методы authenticate и version — работают без аутентификации) и xmlrpc/2/object (метод execute_kw для вызова методов моделей: search, search_read, create, write, name_search). Аутентификация — по API-ключу, который передаётся на месте пароля и в ответ даёт числовой uid.
Вот рабочий каркас скрипта, который мы адаптируем под каждый проект:
import xmlrpc.client
URL = "https://odoo.company.ru"
DB = "production"
USER = "admin@company.ru"
API_KEY = "ваш-api-ключ" # НЕ пароль, а именно API-ключ из настроек пользователя
# 1. Аутентификация → получаем uid
common = xmlrpc.client.ServerProxy(f"{URL}/xmlrpc/2/common")
uid = common.authenticate(DB, USER, API_KEY, {})
if not uid:
raise SystemExit("Аутентификация не удалась: проверьте API-ключ")
models = xmlrpc.client.ServerProxy(f"{URL}/xmlrpc/2/object")
def create_or_update(ext_id, model, vals):
# Идемпотентно: ищем по External ID, обновляем или создаём
# ищем запись, уже связанную с этим external id
found = models.execute_kw(DB, uid, API_KEY,
"ir.model.data", "search_read",
[[["name", "=", ext_id], ["model", "=", model]]],
{"fields": ["res_id"], "limit": 1})
if found:
res_id = found[0]["res_id"]
models.execute_kw(DB, uid, API_KEY, model, "write", [[res_id], vals])
return res_id
# создаём запись
res_id = models.execute_kw(DB, uid, API_KEY, model, "create", [vals])
# регистрируем external id, чтобы повтор не плодил дубли
models.execute_kw(DB, uid, API_KEY, "ir.model.data", "create", [{
"name": ext_id, "model": model, "module": "__import__", "res_id": res_id}])
return res_id
# 2. Заливаем контакты пакетами по 500 с обработкой ошибок
BATCH = 500
errors = []
for i in range(0, len(contacts), BATCH):
for row in contacts[i:i + BATCH]:
try:
create_or_update(f"amo_contact_{row['id']}", "res.partner", {
"name": row["name"],
"is_company": row["is_company"],
"phone": row["phone"],
"email": row["email"],
"vat": row["inn"],
})
except Exception as e:
errors.append((row["id"], str(e)))
print(f"обработано {min(i + BATCH, len(contacts))} из {len(contacts)}")
print("ошибок:", len(errors))
Три вещи, ради которых этот скрипт и написан именно так. Batch по 500 — не заливаем построчно (медленно) и не одним гигантским пакетом (упадёт целиком от одной кривой строки). Обработка ошибок — плохая строка не роняет весь прогон, а попадает в список errors, который потом разбираем отдельно. Идемпотентность через External ID — функция create_or_update сначала ищет запись по внешнему идентификатору и обновляет её, если нашла; повторный запуск скрипта не плодит дубли. В Odoo 19, к слову, появился и новый JSON-2 API как современная альтернатива XML-RPC — логика та же, отличается транспорт; но XML-RPC остаётся самым проверенным и совместимым вариантом для миграции.
Дедупликация — до импорта, а не после
Отдельно и жёстко: дубли ищем и схлопываем ДО загрузки в Odoo, а не после. Разгребать дубли в новой системе в разы дороже, чем в плоском файле. По нашему опыту, типовая база amoCRM за пять лет даёт от 15 до 25 процентов дублей — один и тот же клиент заведён разными менеджерами, с разным написанием названия, с разными телефонами. Это норма, а не патология.
Как ищем дубли — по трём ключам, в порядке надёжности:
- По ИНН — самый надёжный ключ для юрлиц. Один ИНН = одна компания, двух мнений быть не может. Схлопываем без колебаний.
- По e-mail — надёжен для физлиц-контактов, с оговоркой на общие ящики вроде info@ (по такому адресу может «сойтись» полкомпании — тут нужен глаз).
- По телефону в формате +7 — работает только после нормализации, иначе +7 903… и 8 903… не совпадут. Поэтому дедуп по телефону всегда идёт после приведения к единому формату.
Практически это делается так: выгруженные данные грузим в промежуточную таблицу (хоть в тот же PostgreSQL, хоть в pandas), группируем по ключам, размечаем группы дублей, по каждой выбираем «золотую запись» (самую полную и свежую), к ней подтягиваем недостающие поля из дублей — и только «золотые» записи идут на импорт. Работа кропотливая, но именно она определяет, будет ли новая CRM чистой.
Интеграция с почтой — сердце CRM
Данные переехали. Но CRM без почты — это красивая картотека, которую менеджеры бросят через неделю. Настоящая жизнь начинается, когда переписка с клиентом сама подшивается к его карточке. В Odoo это ядро системы, и настроить его надо сразу после миграции.
Входящий алиас: письмо клиента → лид с перепиской
Схема, которую мы разворачиваем у большинства клиентов, работает так: заводится общий почтовый адрес отдела продаж, например sales@вашдомен.ru, и он настраивается как входящий алиас в Odoo. Дальше происходит магия, ради которой всё и делается:
- Потенциальный клиент пишет письмо на sales@вашдомен.ru.
- Odoo забирает это письмо и автоматически создаёт лид (или сделку) в CRM.
- Текст письма, тема и вложения попадают в chatter — ленту сообщений под карточкой. Вся переписка видна прямо в сделке.
- Менеджер отвечает клиенту прямо из карточки Odoo, и его ответ тоже сохраняется в chatter.
Больше никаких «а перешли мне ту переписку», никаких потерянных в личных ящиках договорённостей. История общения с клиентом живёт там же, где сделка, и доступна руководителю и сменщику.
Настройка почтовых серверов: IMAP и SMTP
Технически нужно связать Odoo с вашим почтовиком по двум каналам. В Settings → Technical → Email:
- Incoming Mail Server (входящий, IMAP). Odoo периодически заходит по IMAP в ящик sales@ и забирает новые письма. Указываем сервер, порт (обычно 993 для IMAP over SSL), логин и пароль ящика.
- Outgoing Mail Server (исходящий, SMTP). Через него Odoo отправляет письма — и ответы менеджеров, и уведомления. Указываем SMTP-сервер, порт (587 или 465), учётные данные.
У наших клиентов почта чаще всего живёт на собственном почтовом сервере на базе mailcow — это self-hosted почтовик, который мы разворачиваем и держим на своей инфраструктуре. Тот же принцип, что и с Odoo: данные и переписка остаются под контролем компании, а не в чужом облаке. Odoo и mailcow отлично дружат по стандартным IMAP/SMTP.
Catchall, reply-to и почему ответы падают в ту же сделку
Есть тонкий, но критичный момент. Когда Odoo отправляет письмо из сделки, оно уходит с особым адресом в поле Reply-To — так называемым catchall-адресом (по умолчанию что-то вроде catchall@вашдомен.ru). Когда клиент нажимает «Ответить», его ответ уходит на этот catchall, Odoo его ловит и подшивает ровно к той сделке, из которой ушло исходное письмо. Именно так переписка «склеивается» в единую нить внутри одной карточки, а не рассыпается на разрозненные новые лиды.
Телефония и формы сайта
Почта — половина коммуникаций. Вторая половина — звонки и заявки с сайта. Здесь про Odoo Community надо говорить честно, без прикрас.
Телефония: из коробки звонилки нет
Скажу прямо, потому что на этом обжигаются: в Odoo Community нет встроенной телефонии из коробки. Готовый VoIP-модуль с кнопкой «позвонить» — это функция Enterprise. Но решение есть, и оно рабочее: телефония в Community подключается через сторонние модули (в том числе из репозитория OCA — Odoo Community Association) и коннекторы к вашей АТС.
На практике мы связываем Odoo с Asterisk или FreePBX — свободными телефонными станциями, которые сами по себе покрывают потребности офиса. Что это даёт после настройки:
- Click-to-call — клик по номеру в карточке клиента инициирует звонок через вашу АТС, менеджеру не надо набирать вручную.
- Всплывающая карточка при входящем. Звонит клиент — Odoo по номеру находит его в базе и показывает менеджеру карточку ещё до того, как тот снял трубку. Менеджер сразу видит, кто звонит и какая по нему сделка.
- Логирование звонков — факт и длительность звонка фиксируются как активность в карточке.
Формы сайта — лиды без Tilda и Zapier
А вот здесь Odoo радует. Если у вас подключён модуль Website (он бесплатный, в Community), формы обратной связи и заявки с сайта падают прямо в CRM как лиды — без единого посредника. Не нужен ни Tilda с её выгрузками, ни Zapier с помесячной оплатой за «зробаты», ни самописные вебхуки. Форма на сайте Odoo и воронка Odoo — это одна система, заявка появляется в CRM мгновенно.
Более того, если сайт уже сделан на Odoo Website, вы получаете сквозную картину: посетитель пришёл по рекламе → заполнил форму → стал лидом → менеджер довёл до сделки — и всё это в одной базе, с сохранением источника.
UTM и отчёт по источникам из коробки
Про источники отдельно. Odoo из коробки понимает UTM-метки: campaign, source, medium. Когда лид приходит с формы сайта, метки, с которыми пришёл посетитель, сохраняются в карточке. Дальше во встроенной аналитике вы строите отчёт «сколько сделок и на какую сумму принёс каждый канал» — контекстная реклама, органика, рассылка, конкретная кампания. Это позволяет считать отдачу от маркетинга по деньгам, а не по кликам, и не требует ни доплат, ни доработок.
Связка с 1С — реалистичная архитектура для РФ
Вопрос, который на переговорах в России всплывает всегда: «А с 1С это дружит?». Отвечаю развёрнуто и честно, потому что здесь много иллюзий.
Начну с главного и неприятного для некоторых тезиса: Odoo не заменяет 1С:Бухгалтерию. Российской регламентированной бухгалтерии, первички по нашим формам (УПД, ТОРГ-12, счета-фактуры), отчётности в ФНС в стандартной Odoo нет. И не надо от неё этого ждать. Правильная архитектура для российской компании — разделение труда: Odoo ведёт продажи (воронка, сделки, клиенты, аналитика), 1С ведёт учёт (первичка, бухгалтерия, отчётность). Каждый инструмент делает то, что умеет лучше. Вопрос лишь в том, как между ними передавать данные, и здесь есть три уровня — от простого к сложному.
Уровень 1: руками (до ~20 сделок в месяц)
Самый недооценённый вариант. Менеджер закрыл сделку в Odoo, сформировал счёт — и бухгалтер вручную завёл реализацию в 1С по этому счёту. Всё. Никакой интеграции.
Уровень 2: обмен через файлы по расписанию
Когда сделок становится больше и ручной ввод превращается в рутину, подключаем полуавтоматику: обмен через CSV/Excel по расписанию. Odoo по расписанию выгружает новые закрытые сделки или счета в файл, а 1С этот файл загружает штатными средствами обработки. Направление может быть и обратным — например, из 1С в Odoo подтягиваются актуальные остатки товаров или статусы оплат. Это дёшево, прозрачно и покрывает потребности большинства компаний среднего размера. Файл — понятный формат, который легко проверить глазами, если что-то разошлось.
Уровень 3: двусторонний обмен через OData и XML-RPC
Высший уровень, к которому приходят, когда объёмы большие и данные должны быть синхронны почти в реальном времени. Архитектура: на стороне 1С включается OData или публикуются HTTP-сервисы (1С умеет отдавать и принимать данные по этим протоколам штатно), на стороне Odoo работает XML-RPC (тот самый API из раздела про импорт). Между ними — служба обмена, которая гоняет данные в обе стороны: новый контрагент в Odoo → появляется в 1С; проведена оплата в 1С → статус сделки в Odoo обновился.
Это полноценный интеграционный проект со своим бюджетом, тестированием и сопровождением. Он оправдан, когда цена ручного труда и ошибок ручного переноса превышает стоимость разработки и поддержки моста. Для компании до 50 рабочих мест этот уровень нужен нечасто.
План миграции на неделю и критерии успеха
Соберу всё в практический план. Типовой переезд небольшой компании на Odoo CRM мы укладываем в рабочую неделю. Вот как это выглядит по дням.
| День | Что делаем |
|---|---|
| День 1–2 | Выгрузка из источников (API amoCRM/Bitrix24, нормализация таблиц) и чистка: дедупликация по ИНН/email/телефону, отделение архива от боевых данных |
| День 3 | Тестовый импорт на КОПИЮ базы Odoo. Проверяем маппинг, связи, кастомные поля, считаем ошибки. Правим исходники, повторяем |
| День 4 | Боевой импорт в production. Настройка почтового алиаса, воронки, прав доступа, ответственных менеджеров |
| День 5 | Параллельная работа и сверка: менеджеры работают в Odoo, старая CRM ещё доступна только на чтение. Сверяем контрольные цифры |
Тестовый импорт на копию — не пропускать
День 3 — священный. Первый импорт всегда идёт на копию базы, а не в боевую систему. На копии вы увидите всё: и потерянные при выгрузке телефоны, и разъехавшийся маппинг стадий, и кривые кодировки. Спокойно чините исходники и гоняете импорт заново (спасибо External ID — дублей не будет), пока результат не станет чистым. И только выверенный набор данных заливаете в production на день 4.
Параллельная работа и заморозка ввода
Пара слов про переключение. На день 4, перед боевым импортом, старую CRM надо заморозить на ввод — перевести в режим «только чтение» или хотя бы административно запретить заводить в ней новые записи. Иначе вы попадёте в классическую ловушку, о которой ниже. Несколько дней старая система остаётся доступной для просмотра — чтобы менеджеры при сомнениях могли свериться, — но вся новая работа идёт уже в Odoo.
Критерий успеха — измеримый
Как понять, что переезд удался? Не по факту «данные залились», а по поведению людей. Главная метрика: через две недели после переезда менеджеры перестали открывать старую CRM. Если открывают — значит, в Odoo чего-то не хватает: не переехало важное поле, неудобна воронка, не настроена почта. Это сигнал доделать, а не ругать сотрудников. Если не открывают и спокойно работают в Odoo — переезд состоялся, старую систему через месяц-другой можно гасить, оставив архивную выгрузку.
Миграция CRM — это не «залить CSV», а управляемый проект: решить что везём, аккуратно выгрузить, вычистить дубли, грамотно смапить, импортировать через копию с идемпотентностью, а потом обвязать почтой, телефонией и — по-умному — связкой с 1С. Сделаете так — не потеряете ни одного клиента из пятилетней базы.
Если браться за это самим некогда или страшно рисковать боевыми данными — мы в ITfresh делаем такие переезды под ключ. Выгрузим из amoCRM, Bitrix24 или ваших таблиц, вычистим дубли, перенесём в Odoo без потерь, настроим почту, телефонию и обмен с 1С, а сервер возьмём на сопровождение в нашем дата-центре МТС. Пишите в Telegram @ITfresh_Boss или звоните +7 903 729-62-41 — разберём вашу ситуацию без обязательств.
Оставить комментарий