Разработка кастомных фильтров Битрикс24
Встроенный фильтр Битрикс24 работает по принципу «поле — оператор — значение». Для простых выборок этого достаточно. Но когда нужно отфильтровать сделки по агрегированным данным (сумма оплат за период > порога), по связанным сущностям (контакты, у которых есть сделки на определённой стадии) или по данным из внешней системы (клиенты с задолженностью в 1С) — стандартный фильтр бесполезен. Он не умеет join, не поддерживает подзапросы и не знает о внешних источниках.
Как устроен стандартный фильтр
В Битрикс24 за фильтрацию отвечает JS-компонент BX.Main.Filter. Он рендерит панель фильтров, собирает пользовательский ввод и передаёт его в backend-обработчик. В коробочной версии фильтр оперирует ORM-классами: \Bitrix\Crm\DealTable, \Bitrix\Crm\ContactTable и т.д. Каждое поле фильтра маппится на колонку ORM-сущности.
В облачной версии фильтрация происходит через REST API — параметр filter в методах crm.deal.list, crm.item.list. Поддерживаемые операторы:
-
=— точное совпадение -
!— не равно -
<,>,<=,>=— сравнение -
%— содержит (LIKE) - Массив значений — IN
Нет: группировки условий (AND/OR на уровне фильтра), агрегатных функций, подзапросов.
Кастомный фильтр: архитектура
Кастомный фильтр — это REST-приложение, которое реализует собственную логику выборки и возвращает результат в интерфейс Б24. Архитектура состоит из трёх слоёв:
1. UI фильтра — ваш интерфейс в iframe (placement LEFT_MENU или CRM_*_LIST_TOOLBAR). Пользователь задаёт параметры фильтрации: период, порог суммы, тип связанной сущности.
2. Backend-обработчик — ваш сервер, который принимает параметры фильтра, выполняет сложную выборку и возвращает список ID подходящих элементов.
3. Отображение результатов — отфильтрованные данные показываются в вашем кастомном списке или передаются обратно в стандартный список через предустановленный фильтр.
Глубокое погружение: фильтрация по агрегатам
Задача: показать менеджеру сделки, по которым сумма оплат за последние 30 дней меньше 50% от суммы сделки. Стандартный фильтр так не умеет.
Шаг 1: сбор данных. Backend-обработчик запрашивает все активные сделки через crm.deal.list с фильтром STAGE_SEMANTIC_ID=P. Для каждой сделки получает товарные позиции и историю оплат через crm.timeline.list или кастомное поле с суммой оплат.
Шаг 2: агрегация на бэкенде. Это ключевой момент — вычисления делаются на вашем сервере, а не в браузере. Для каждой сделки:
процент_оплаты = сумма_оплат_30дней / сумма_сделки * 100
если процент_оплаты < 50 → включить в результат
Шаг 3: кэширование. Результат агрегации кэшируется (Redis, memcached) с TTL 15–30 минут. Повторное открытие фильтра не вызывает пересчёт.
Шаг 4: отображение. Список ID отфильтрованных сделок отдаётся в UI, который рендерит таблицу с нужными колонками. Или — более элегантно — формируется предустановленный фильтр ID в стандартном списке:
// Открываем стандартный список с предустановленным фильтром
BX24.openPath('/crm/deal/list/?apply_filter=Y&ID[]=' + filteredIds.join('&ID[]='));
Фильтрация по связанным сущностям
Сценарий: найти все компании, у которых есть хотя бы одна сделка на стадии «Переговоры» с суммой > 1 000 000.
В стандартном фильтре компаний нет полей сделок. Решение:
- Запрос
crm.deal.listс фильтром по стадии и сумме → получаемCOMPANY_IDиз каждой сделки - Уникальные
COMPANY_ID→ массив ID для фильтра компаний - Запрос
crm.company.listсfilter: {ID: uniqueCompanyIds}→ финальный список
На вашем бэкенде это один SQL-запрос с JOIN. Через REST API — цепочка из 2–3 запросов. Для регулярного использования такого фильтра создайте серверный endpoint, который выполняет агрегацию и возвращает готовый результат.
Кастомные пресеты фильтров
Помимо динамических фильтров, часто нужны сохранённые пресеты: «Просроченные > 7 дней», «VIP-клиенты без активности», «Сделки без задач». В REST API нет метода для программного создания пресетов стандартного фильтра Б24. Решение — кастомный UI с кнопками-пресетами:
var presets = {
overdue_7: {'>DATE_CLOSE': formatDate(-7), 'STAGE_SEMANTIC_ID': 'P'},
vip_inactive: {'UF_CRM_VIP': 1, '<DATE_MODIFY': formatDate(-30)},
no_tasks: {} // Требует серверной логики
};
function applyPreset(name) {
loadFilteredData(presets[name]);
}
Пресет «Сделки без задач» — пример фильтра, невозможного через REST: нужно проверить отсутствие связанных задач у каждой сделки. Это решается batch-запросом tasks.task.list с фильтром UF_CRM_TASK для каждой сделки или серверной агрегацией.
Производительность и лимиты
REST API Битрикс24 ограничивает количество запросов: 2 запроса в секунду для одного приложения, 50 команд в batch. Для фильтра, который должен обработать 10 000 сделок:
| Подход | Запросов | Время |
|---|---|---|
| Последовательные запросы по 50 | 200 | ~100 сек |
| Batch по 50 команд | 4 batch-запроса | ~8 сек |
| Серверный кэш + инкрементальное обновление | 1–2 запроса | <1 сек |
Для production-фильтров с большими объёмами единственный рабочий подход — серверный кэш с периодической синхронизацией. Ваш сервер хранит копию данных CRM, обновляемую через вебхуки (onCrmDealUpdate) или по расписанию, и выполняет фильтрацию локально.
Коробочная версия: фильтры через ORM
В коробочной Б24 кастомный фильтр можно реализовать на уровне PHP — расширение стандартного фильтра новыми полями. Через событие onBuildFilterFields добавляется кастомное поле, а обработчик onBuildFilterQuery модифицирует SQL-запрос. Это производительнее REST-подхода, но требует доступа к серверу и обновляется вместе с модулем.







