Download the PHP package bxshef/leadfinish without Composer

On this page you can find all versions of the php package bxshef/leadfinish. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.

FAQ

After the download, you have to make one include require_once('vendor/autoload.php');. After that you have to import the classes with use statements.

Example:
If you use only one package a project is not needed. But if you use more then one package, without a project it is not possible to import the classes with use statements.

In general, it is recommended to use always a project to download your libraries. In an application normally there is more than one library needed.
Some PHP packages are not free to download and because of that hosted in private repositories. In this case some credentials are needed to access such packages. Please use the auth.json textarea to insert credentials, if a package is coming from a private repository. You can look here for more information.

  • Some hosting areas are not accessible by a terminal or SSH. Then it is not possible to use Composer.
  • To use Composer is sometimes complicated. Especially for beginners.
  • Composer needs much resources. Sometimes they are not available on a simple webspace.
  • If you are using private repositories you don't need to share your credentials. You can set up everything on our site and then you provide a simple download link to your team member.
  • Simplify your Composer build process. Use our own command line tool to download the vendor folder as binary. This makes your build process faster and you don't need to expose your credentials for private repositories.
Please rate this library. Is it a good library?

Informations about the package leadfinish

[SH-local] Своя кнопка завершения лида (shef.leadfinish)

CI Packagist Bitrix24 self-hosted

Модуль для Битрикс24. Позволяет завершить обработку лида, привязав к нему уже существующую сделку, — вместо штатного создания новой.

Разработчик — ИП Шевчик И.С., bx-shef.by.


Зачем это нужно

Штатное поведение Битрикс24: менеджер жмёт «Завершить обработку лида», и портал предлагает создать новую сделку на основании лида.

На практике сделка часто уже создана — заказ пришёл из другой системы и лежит в CRM под номером вида «Заказ покупателя 00КА-66901». Менеджеру нужно не создавать дубль, а связать лид с этой сделкой и закрыть лид.

Модуль подменяет зелёную кнопку в попапе завершения на свою — «Подобрать сделку».

Как это выглядит для менеджера

  1. Менеджер жмёт «Завершить обработку лида» — в карточке лида либо прямо в строке списка лидов.
  2. Открывается штатный попап «Выберите результат…». Вместо зелёной «Создать на основании: Сделку» в нём стоит «Подобрать сделку». Красная «Забраковать» остаётся на месте и работает как обычно.
  3. По нажатию открывается окно подбора с одним полем.
  4. Менеджер вводит номер заказа — например 66901. Список обновляется на лету.
  5. По каждой найденной сделке видно: название, сумму с валютой, стадию, воронку и есть ли уже связь с лидом. Рядом — ссылка «Открыть ↗»: сделка откроется в новой вкладке, подбор при этом не закроется.
  6. Менеджер выбирает строку и жмёт «Выбрать». Окно блокируется на время сохранения.
  7. Оба окна закрываются, появляется уведомление, открывается слайдер привязанной сделки. Если подбор открывали из списка, таблица сразу перечитывается — строка показывает новую стадию, перезагружать страницу не нужно.

Кнопка «Отмена» просто закрывает подбор — с лидом ничего не происходит.

Где работает

Место Как выглядит
Карточка лида, в том числе открытая в слайдере вместо зелёной кнопки — «Подобрать сделку»
Список лидов то же, прямо в строке
Канбан лидов в окне «Создать на основании лида:» — пункт «Подобрать сделку»

В канбане окно открывается не кнопкой, а перетаскиванием карточки лида в колонку «Сделка» (или в нижнюю зону «Сделка»). Ядро показывает там список вариантов конвертации — вместо них остаётся один наш пункт.

После привязки доска перечитывается: лид закрыт и уходит с неё сам. Если закрыть окно, ничего не выбрав, карточка возвращается в исходную колонку — как и при штатной отмене.

Что происходит внутри при нажатии «Выбрать»

Шаг Действие
1 В сделку записывается LEAD_ID — связь с нашим лидом
2 Лид переводится в статус CONVERTED («обработан успешно»)
3 В таймлайн лида: Лид привязан к сделке «…» (#id)
4 В таймлайн сделки: К сделке привязан лид «…» (#id)
5 Ответ уходит на клиент, окна закрываются, открывается слайдер сделки

Перевод лида в CONVERTED — штатная операция CRM, поэтому ядро само регистрирует статистику конверсии и историю стадий.

Порядок шагов намеренный: сначала связь, потом закрытие лида. Если второй шаг упадёт, останется привязанная сделка при открытом лиде — это заметно и чинится повторным нажатием. Обратный порядок дал бы закрытый лид без связи, что заметить куда труднее.

Запись в таймлайн — вспомогательная: её ошибка не отменяет уже выполненную привязку, а уходит в журнал (AddMessage2Log).

Правила подбора

Сделки, уже привязанные к другому лиду, показываются с пометкой, и выбрать их можно — прежняя связь будет перезаписана.

Установка

Порядок здесь важен: шаг 3 правит файл, который раскладка файлов на шаге 2 перетирает — и архивом, и Composer'ом. Сделать наоборот — список вернётся к поставочному, и кнопку никто не увидит.

1. Узнать ID тех, кому нужна кнопка

Открыть профиль сотрудника — ID стоит прямо в адресе:

Число в адресе (44) и есть ID. То же самое видно в админке: Настройки → Пользователи → Список пользователей, столбец ID.

Выписать ID всех, кому кнопка нужна: менеджеров, которые завершают лиды, и свой собственный — чтобы было под кем проверять.

2. Положить файлы в портал

Через Composer. Настраивать пути не нужно — пакет приезжает туда, куда надо, сам:

Единственное, что требуется в composer.json проекта, — разрешить плагин раскладки. Это требование самого Composer, обойти его нельзя:

Забыли — Composer остановится с ошибкой и не поставит ничего. Тихо не туда не уедет.

⚠ composer.json должен лежать в корне портала: путь к модулю считается относительно него. Из подкаталога модуль уедет в local/bitrix/modules/... — молча. Как это обойти и что ещё проверить — в docs/install-via-composer.md.

Архивом из релиза. Скачать shef.leadfinish.zip со страницы релизов:

local/modules/ тоже работает — фронт модуля от его расположения не зависит, см. ниже.

3. Вписать ID в .settings.php

Открыть /home/bitrix/www/bitrix/modules/shef.leadfinish/.settings.php и заменить список в allowed_users на тот, что выписали в шаге 1:

В поставке там стоит [1] — это администратор портала, и только он. Пока список не поправлен, менеджер кнопки не увидит, а выглядеть это будет как «модуль не работает».

⚠ Очистить список, чтобы «пока выключить», нельзя — пустой список значит ровно обратное: кнопка появится у всех авторизованных. Разбор всех случаев — в разделе «Кому показывается» ниже.

4. Установить модуль

Админка → Marketplace → Установленные решения → «[SH-local] Своя кнопка завершения лида» → Установить.

Composer только раскладывает файлы — этот шаг он не заменяет.

⚠ Ставить из консоли не надо. ModuleManager::registerModule() только помечает модуль установленным: он не регистрирует обработчик события и не копирует фронт. Получится модуль, который числится установленным и ничего не делает, а искать причину будете в коде.

Установка регистрирует обработчик main::OnEpilog и копирует фронт в /bitrix/js/shef.leadfinish/. Настроек в базе модуль не создаёт: весь список доступа — это файл из шага 3.

⚠ Без этого шага кнопки не будет, даже если файлы разложены: каталог модуля браузеру недоступен. В поставке nginx стоит location ~* ^/bitrix/(modules|local_cache|…) { deny all; }, и запрос к /bitrix/modules/shef.leadfinish/js/... отдаёт 403. Поэтому JS и CSS переезжают туда, откуда отдаются, — так же делают штатные модули Битрикса.

Побочный итог: путь к фронту не зависит от того, куда положен модуль, и bitrix/modules/ с local/modules/ работают одинаково.

5. Сбросить кеш JS/CSS

Битрикс отдаёт склеенные файлы из /bitrix/cache/js/s1/..., и без сброса до браузера доедет прежний набор. Админка → Настройки продукта → Автокеширование → сбросить. Либо Ctrl+F5 в браузере.

6. Проверить под тем, кому кнопка нужна

Зайти под менеджером из шага 1, а не под собой, открыть лид и нажать «Завершить обработку лида». Вместо зелёной «Создать на основании: Сделку» должна стоять «Подобрать сделку».

Не появилась — раздел «Отладка» в конце.

Обновление

⚠ И то и другое перетирает .settings.php вместе со списком allowed_users и расписанием приостановки.

Надёжный способ один: держать нужные значения в самой поставке — в репозитории, откуда собираются и архив, и Composer-пакет. Тогда обновление приезжает уже настроенным, и возвращать нечего. Правите только на сервере — выписывайте перед обновлением (cat .settings.php) и возвращайте после.

Переустановка через админку нужна, только если менялись события установки. Менялись lib/, js/, css/ — хватит раскладки файлов и сброса кеша.

Удаление

Там же кнопкой Удалить. Снимается обработчик события; заодно чистятся настройки в базе, оставшиеся от версий до 1.4.0. Файлы каталога остаются — их удалять вручную.

Привязки, сделанные модулем, при удалении не откатываются: LEAD_ID и статусы лидов остаются как есть. Это обычные данные CRM, а не служебные записи модуля.

Кому показывается

Список живёт в .settings.php модуля, ключ allowed_users — это шаг 3 установки. Здесь разобрано, что в нём можно написать.

В поставке стоит один администратор портала:

Пустой список = кастомизация работает для всех авторизованных. Так задумано: после обкатки на нескольких людях включить её на всех можно, просто очистив список, без правки кода. Обратная сторона — очисткой список не «выключить»: получится не «никому», а «всем».

Тот же список проверяется и в ajax-действиях, не только при показе кнопки — иначе действие осталось бы вызываемым по прямому адресу.

Страницы настроек в админке у модуля нет намеренно: два источника одной правды (файл и база) рано или поздно разойдутся, и тогда непонятно, какой из них действует.

Случаи, которые легко перепутать:

В .settings.php Кому доступно
'value' => [44, 562] только этим ID
'value' => [] — список пуст всем авторизованным
ключа allowed_users нет вовсе никому: доработка не настроена
'value' => ['abc'], [[44]], '4 4' — нечитаемо никому: опечатка не должна ни раскатывать кнопку, ни выдавать её постороннему

Последние два разведены нарочно. Отсутствие ключа — это обычно неполное обновление: распаковали lib/, а .settings.php на сервере остался старый. Считать это за «пусто» значило бы молча включить кнопку всему порталу.

⚠ Файл перетирается при обновлении модуля (распаковка архива с -o), в отличие от прежней настройки в базе. Правите список на сервере — поправьте его и в репозитории, иначе следующая поставка вернёт прежний.

Приостановка доработки

Пока приём выполненных работ не оформлен, доработка сначала напоминает об этом, а потом перестаёт открываться. Две ступени:

Ступень Что происходит
soft При нажатии «Подобрать сделку» показывается экран с отсчётом на 20 секунд, затем подбор открывается как обычно
hard Подбор не открывается. Экран объясняет причину

На жёсткой ступени штатная зелёная кнопка ядра остаётся видимой и рабочей. Приостанавливается наша доработка, а не CRM заказчика: спрятав кнопку ядра и заблокировав свою, мы отняли бы у менеджера саму возможность завершить лид.

Жёсткая ступень запрещается и на сервере, в ajax-действиях, — иначе приостановка снималась бы правкой JS в консоли браузера.

Анимация (экскаватор, который пытается поднять стрелу и не может) отключается по prefers-reduced-motion. Без движения рисунок остаётся осмысленным.

Настройка

Расписание живёт в .settings.php модуля, раздел lock:

Почему в файле, а не в базе и не в коде: снимать приостановку нужно быстро — правкой одного файла на сервере, без пересборки и переустановки модуля.

Любая ошибка в настройках уводит в сторону работающей доработки: негодная дата отбрасывается, мусор в off выключателем не считается, нечитаемый список users не означает «приостановить всем». Приостановить не того из-за своей же опечатки хуже, чем не показать напоминание.

Каждая дата работает и в одиночку: только soft_from — напоминание без последующей блокировки, только hard_from — блокировка без предупреждения. Жёсткая дата проверяется первой, поэтому перепутанные местами даты дают «жёстко с более ранней», а не тихую бессмыслицу.

Посмотреть экран, не дожидаясь даты, — ?lock=soft или ?lock=hard в адресе карточки лида. Обход умеет только повышать ступень: ?lock=none не существует, иначе такая ссылка разошлась бы по переписке за минуту.

Рубильник off гасит и обход. После того как приостановку сняли, старая ссылка с ?lock=hard из переписки ничего не покажет — иначе менеджер видел бы экран приостановки, которой уже нет, а сервер в этот момент действие разрешает.

Как это устроено технически

Ядро Битрикса не изменяется

Попап завершения — обычный BX.PopupWindow. Класс PopupWindow объявляет namespace BX.Main.Popup и эмитит onAfterShow, поэтому попап ловится штатным событием:

Опорные точки в ядре (bitrix/js/crm/progress_control.js):

Что Где формируется
id попапа <controlId>_TERMINATION BX.CrmProgressControl
id обёртки кнопки <controlId>_success_btn_wrapper BX.CrmLeadTerminationControl.prepareDialogControls

Обе завязки — на суффикс id, так что переименование самого контрола ничего не ломает.

Оригинальная кнопка не удаляется, а скрывается. На открытии попапа ядро вешает на её внутренности селектор схем конверсии (BX.CrmLeadConversionSchemeSelector), а на закрытии дёргает его release(). Удаление узла оставило бы селектор со ссылками на несуществующий DOM.

Оба окна закрываются через объекты попапов, а не скрытием узлов стилями: спрятанный через display:none попап продолжает считать себя открытым и ломает следующее открытие.

Серверная часть

Всё на универсальном API CRM (Service\Container, Factory, Operation с enableCheckAccess()), а не прямыми запросами к базе: операции сами делают нормализацию данных, историю, индексацию и проверку прав.

Ajax-действия:

Оба защищены штатными фильтрами: авторизация, только POST, проверка csrf-токена.

Состав

Файл Назначение
install/index.php установка/удаление, регистрация обработчика
.settings.php контроллеры, список доступа, расписание приостановки
lib/access.php кому доступна кастомизация (общий источник правды)
lib/userlist.php разбор списка ID из настроек, общий для доступа и приостановки
lib/lock.php ступень приостановки: расписание, календарь, кого касается
lib/eventhandler.php подключение JS/CSS на страницах лида
lib/dealsearch.php подбор сделок с учётом прав
lib/binder.php привязка сделки, закрытие лида, таймлайны
lib/controller/dealbinder.php ajax-действия search и bind
js/lead-finish-button.js подмена кнопки и окно подбора
css/lead-finish.css оформление подбора
composer.json имя и тип пакета для установки через Composer
CLAUDE.md памятка для AI-агента: инварианты, ловушки, что не переигрывать

JS и CSS подключаются только там, где попап завершения существует, и только пользователям из списка: скрипт вешает глобальный слушатель попапов, и на остальных страницах портала он не нужен.

Файлы модуля лежат в корне репозитория — этого требует Composer, который разворачивает в целевой каталог корень пакета целиком. Всё, что на портал не едет (tests/, docs/, build.sh, CONTRIBUTING.md, .github/), отсечено через export-ignore в .gitattributes и исключено из сборки архива.

Отладка

В js/lead-finish-button.js вверху var DEBUG — по умолчанию false. Поставь true, и в консоли будет видно, что слушатель встал и что кнопка подменена.

Кнопка не появилась:

Подбор ничего не находит:

Ошибка при нажатии «Выбрать» — текст приходит от ядра как есть. Чаще всего это недостаток прав на изменение сделки или лида.

Совместимость

Проверено на Битрикс24 с модулем crm. Опорные точки — публичные события ядра и универсальное API CRM; при обновлении платформы отдельно стоит проверить, что попап завершения лида по-прежнему BX.PopupWindow с id <controlId>_TERMINATION.

Разработка

Ветки, коммиты, PR и чек-лист перед мержем — в CONTRIBUTING.md. Коротко: в main не пушим, всё через PR, мержит владелец.

Проверки и сборка — из корня репозитория:

Скрипт делает php -l и node --check, гоняет тесты из tests/, ловит заглавные буквы в именах файлов lib/ (ломают автозагрузку только на Linux), показывает версию и проверяет, что внутри архива первым уровнем лежит shef.leadfinish/. Ровно то же гоняется в CI на каждый PR — собранный архив прикладывается к прогону, его можно скачать и поставить, не собирая руками.

Подробности: docs/build-and-install.md — сборка и установка, docs/module-structure.md — как устроен локальный модуль Битрикс24.

Релиз

Поставка на постоянной ссылке. Два способа, результат одинаковый:

Кнопкой — Actions → Release → Run workflow от main. Тег выводится из VERSION в install/version.php и ставится сам, поэтому разойтись им негде.

Тегом с рабочей машины:

Дальше всё делает CI: сверяет тег с VERSION (не совпали — релиза не будет), собирает архив и выкладывает релиз с приложенным shef.leadfinish.zip и списком изменений с прошлого тега.

Зачем отдельно от артефакта прогона: артефакт живёт 14 дней, релиз — всегда. Через полгода на вопрос «что именно стоит на портале» отвечает страница релиза, а не память.

Нужна своя доработка Битрикс24?

Этот модуль сделан под конкретную задачу: процесс не ложился на коробочное поведение, а в маркетплейсе такого не было. Интеграция, AI-помощник, своя логика вместо стандартной — собирается под задачу.

Описать задачу за 5 минут →

Дальше оценка, фиксированная цена за этап или почасовая ставка и демо каждые 1–2 недели. Останавливаете проект — платите только за сделанное.

Лицензия

MIT.


All versions of leadfinish with dependencies

PHP Build Version
Package Version
Requires php Version >=8.1
composer/installers Version ^1.0 || ^2.0
Composer command for our command line client (download client) This client runs in each environment. You don't need a specific PHP version etc. The first 20 API calls are free. Standard composer command

The package bxshef/leadfinish contains the following files

Loading the files please wait ...