Розробка користувацьких фільтрів у Bitrix24
Вбудований фільтр Bitrix24 працює за принципом «поле — оператор — значення». Для простих вибірок цього досить. Але коли потрібно відфільтрувати угоди за агрегованими даними (сума платежів за період > порогу), за пов'язаними сутностями (контакти, у яких є угоди на певній стадії) або за даними з зовнішної системи (клієнти з заборгованістю в 1С) — стандартний фільтр марний. Він не вміє join, не підтримує підзапити та не знає про зовнішні джерела.
Як влаштований стандартний фільтр
У Bitrix24 за фільтрацію відповідає 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 Bitrix24 обмежує кількість запитів: 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-підхід, але потребує доступу до сервера та оновлюється разом з модулем.







