Представляю вашему вниманию цикл статей по работе с пока еще мало знакомым многим битрикс-разработчикам инструментом оперирования данными с CRM Битрикс24 через абстрактные фабрики. В первой статье рассмотрим базовые операции с элементами сущностей CRM — создание, изменение, удаление.


Вышедший год назад, но уже «перевернувший» структурное восприятие многих Битрикс24 интеграторов на «до и после», модуль «Смарт-процессы», все активнее и активнее используется при автоматизации различных задач. Гибкость модуля, по сути позволяющая создавать новые сущности CRM в неограниченном количестве, по достоинству оценена пользователями. Но вот для разработчиков, особенно привыкших для оперирования элементами использовать уже привычные методы BitrixAPI, например такие классы как CCrmDeal, CCrmLead и пр. оказалось в части смарт процессов все не так просто и однозначно. Обращение к элементам и изменение их происходило через привычные всем Битрикс разработчикам методы, например GetList, Add, Update.

В случае смарт процессов же именовать выделенные классы потеряло смысл, так как теперь смарт-процессов может быть любое количество, и наименования они могут иметь любые по желанию пользователей. Данная статья поможет начинающим разработчикам обрести понимание принципов работы с элементами Смарт-процессов в коробочной версии Битрикс24.

Начнем со структурного понимания работы с новыми сущностями. Как я уже писал выше, теперь Смарт-Процессов может быть до 64, с любыми наименованиями. Поэтому для реализации методов оперирования данными процесса в ядре был реализован специальный метод по шаблону проектирования «Абстрактная фабрика».

Если упростить механизм для понимания, теперь для любой сущности CRM Битрикс24 (не только Смарт-процессов) можно инициализировать такую фабрику, и дальше через ее методы оперировать параметрами и элементами сущности.

Да, для стандартных сущностей оставили старые классы в качестве обратной совместимости. А также в старые классы «прокинули» поля связки со Смарт-процессами. Но с самим Смарт-процесса без нового «фабричного» API сделать ничего не получится.

1. Инициализация фабрики

Пример инициализации фабрики выглядит следующим образом:use Bitrix\Main\Loader;

use Bitrix\Crm\Service;

Loader::includeModule('crm');

$typeid = '124';//Идентификатор смарт-процесса

$factory = Service\Container::getInstance()->getFactory($typeid);  


Также в качестве typeid можно передать идентификатор сущности CRM из класса \CCrmOwnerType, например \CCrmOwnerType::Deal. То есть по факту фабрику можно инициализировать для любой сущности CRM. Подробнее о том как именованы идентификаторы других сущностей и примеры их передачи в фабрику указаны здесь, в фабрику для создания передаем в виде entityTypeID, указанного по ссылке.

После инициализации фабрики становятся доступными все методы, доступные абстрактной фабрике CRM. Они подробно расписаны в официальной документации тут.

Далее разберем наиболее часто встречающиеся в задачах для разработчиков.

2. Получение стадий сущности из фабрики

Так как Смарт-Процесс помимо возможности содержать указанные пользователем поля с данными также может содержать и нетиповую статусную модель, разработчику нужно знать, какие статусы использует процесс перед операциями с данным процессом.

use Bitrix\Crm\Service\Container;

$factory = Container::getInstance()->getFactory($entityTypeID)

if ($factory && $factory->isStagesSupported())

{

$stages = $factory->getStages()->getAll();

foreach( $stages as $stage){

$arStages = $stage->getStatusId();

}

}

будет возвращен массив типа

DT124_6:NEW,DT124_6:PREPARATION,DT124_6:CLIENT,DT124_6:SUCCESS,DT124_6:FAIL,

где 124 -  идентификатор типа смарт-процесса, а 6 — ид смарт-процесса.

3. Создание элемента смарт-процесса

Для создания нового элемента через фабрику теперь недостаточно просто запустить метод создания. Операция создания теперь тоже формирует свой подобъект, в котором после всех необходимых действий нужно выполнить метод запуска операции. Только после этого нужный объект будет создан. Рассмотрим пример создания элемента в простейшем виде:

use Bitrix\Crm\Service\Container;

$faсtory = Container::getInstance()->getFactory($entityTypeId);

$data = [

               'TITLE' => ‘Название элемента’,

               ‘ASSIGNED_BY_ID’=>$userId,

               'UF_CRM_1_DATE' => new Bitrix\Main\Type\DateTime(),

               'PARENT_ID_2' => $dealId,

               "STAGE_ID"  =>  "DT124_6:NEW",

 ];

$item = $factory ->createItem($data); 

$item->save();

Также процесс создания можно дополнительно кастомизировать, к примеру добавив через объект Context пользователя, под которым данное действие будет выполнено. К примеру, код будет выполняться в агенте и нам нужно установить пользователя руками. В этом случае наш пример приобретает вид:

use Bitrix\Crm\Service\Container;

$factory = Container::getInstance()->getFactory($entityTypeId);

$context = new \Bitrix\Crm\Service\Context();

$context -> setUserId($userId);

data = [

               'TITLE' => ‘Название элемента’,

               ‘ASSIGNED_BY_ID’=>$userId,

               'UF_CRM_1_DATE' => new Bitrix\Main\Type\DateTime(),

               'PARENT_ID_2' => $dealId,

               "STAGE_ID"  =>  "DT124_6:NEW",

 ];

$item = $factory ->createItem($data); 

$saveOperation = $factory ->getAddOperation($item, $context);

$operationResult = $saveOperation->launch();

То есть по сравнению с привычным API разработчик теперь глубже воздействовать на процесс оперирования данных, не вклиниваясь при этом в методы ядра Битрикс.

4. Изменение элемента Смарт-процесса

Для изменения элементов в фабрике есть 2 подхода — изменение одного поля конкретного элемента и изменение нескольких полей через массив. Также есть возможность по аналогии с операцией создания через Context кастомизировать операцию изменения.

Рассмотрим простую операцию изменения одного поля элемента:

use Bitrix\Crm\Service\Container;

$factory = Container::getInstance()->getFactory($entityTypeId);

$item = $factory->getItem($entityId);

$item->set('UF_CRM_1_FIELD', $value);

$item->save();

Если нужно изменить несколько полей за одну операцию, код приобретает вид:

use Bitrix\Crm\Service\Container;

$factory = Container::getInstance()->getFactory($entityTypeId);

$class = $factory -> getDataClass();

 $saveResult = $class::update($id, $arUpdate);

В массив arUpdate кладем уже привычные с традиционных методов апи новые значения полей, в ключи массива — идентификаторы полей в которые эти значения нужно вписать.

Если нужно кастомизировать операцию изменения, по аналогии с уже рассмотренной операцией создания используем контекст для указания пользователя, под которым операция будет выполнена:

use Bitrix\Crm\Service\Container;

$factory = Container::getInstance()->getFactory($entityTypeId);

$context = new \Bitrix\Crm\Service\Context();

$context -> setUserId($userId);

$item = $factory->getItem($entityId);

$saveOperation = $factory ->getUpdateOperation($item, $context); 

$operationResult = $saveOperation->launch();

5. Удаление элемента Смарт-процесса

Для удаление элемента смарт-процесса нам понадобится использовать уже знакомый нам по этой статье Context. Удаление возможно на момент написания статьи только с его использованием. Рассмотрим пример удаления элемента:

use Bitrix\Crm\Service\Container;

$faсtory = Container::getInstance()->getFactory($entityTypeId);

$item->$item->getItem($entityId);

 $saveOperation = $factory->getDeleteOperation($item, $context);

 $operationResult = $saveOperation->launch();

Планы на следующие части

В рамках цикла статей по работе со Смарт-процессами через API Битрикс24 коробочной версии планируются еще статьи:

2. Работа со списком элемента Смарт-процесса и связями между ними
3. Как реализовать обработчики события для Смарт-процессов

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

Вместо заключения

В комментариях к данной записи был бы рад услышать мнение других разработчиков Битрикс24 по поводу нового API CRM. Насколько оно удобно для понимания? Всем спасибо за внимание.

Также хочу порекомендовать к посещению бесплатный вебинар от моих коллег из OTUS на котором мы рассмотрим как создавать свои таблицы в БД Битрикс24. Создадим комплексный компонент списка, включая такие элементы как фильтр, пагинация, кнопки действий.
Вы научитесь: создавать свои компоненты для Битрикс24, добавлять выгрузку данных списка в Excel, добавлять свои данные и действия в шаблон.

Подробнее о бесплатном вебинаре

Комментарии (7)


  1. gromdron
    30.05.2023 14:02
    +2

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

    Подробности под катом.

    Недочеты статьи

    Гибкость модуля, по сути позволяющая создавать новые сущности CRM в неограниченном количестве,

    "Неограниченное количество" на момент написания комментария составляет 64 смарт-процесса и не больше.

    теперь для любой сущности CRM Битрикс24

    В настоящий момент времени фабрики для старых сущностей (Лид, Сделка, Контакт, Компания) работают в экспериментальном режиме и не смотря на то, что на текущий момент существует возможность работать с ними через фабрики, обратиться в техподдержку с ошибками по такой работе вряд ли получиться.

    Прямое сохранение и работа с самим объектом Bitrix\Crm\Item (т.е. то что вы делаете в самом первом способе сохранения элемента) через:

    $item = $factory ->createItem($data); 
    $item->save();
    

    Вообще не рекомендовано! Этот способ не проверяет права, не запускает бизнес-процессы/автоматизацию, не производит валидацию бизнес-логики пользовательских полей и очень важно - не пересчитывает права для видимости элемента.

    И в следующем примере вы вроде как исправились и указали фабрику (но тут же встретили копипасту в виде fabrika), но совсем никак не обработали успешность операции и оставили просто переменную $operationResult.
    Вы пишете статью из которых многие будут копипастить код, копипасть подходы и копипастить ошибки. Зачем?

    Далее вы показываете замечательный антипример "Если нужно изменить несколько полей за одну операцию, код приобретает вид".
    Нет, не приобретает и так как вы делаете вообще делать не стоит. Ваш код будет выглядеть например так:

    // ... 
    $factory = Container::getInstance()->getFactory($entityTypeId);
    
    $item = $factory->getItem($entityId);
    
    // Вот прямо так через `set` мы можем поменять другие поля
    $item->set('UF_CRM_1_FIELD_1', $value1)
    	->set('UF_CRM_1_FIELD_2', $value2)
        ->setUfCrm1Field3($value3) // или вот так например
    	;
    
    $operation = $factory->getAddOperation($item);
    
    $operationResult = $operation->launch();
    
    if ( !$operationResult->isSuccess() )
    {
    	/**
    	 * Что-то пошло не так, обработаем ошибки из:
    	 *
    	 *
    	 * @operationResult->getErrors();
    	 *
    	 * Или из
    	 *
    	 * @operationResult->getErrorMessages();
    	 */
    }
    

    Если нужно кастомизировать операцию изменения

    Смотря что вы вкладываете в понятие кастомизировать. Указанный код я бы назвал сменой контекста выполнения, а конкретно пользователя, чьи права будут проверяться и чье имя будет использоваться при записи в историю и автоматизации.

    Под кастомизацией обычно понимается изменение поведение или дополнительные действия — например отправить уведомление при создании элемента смарт‑процесса (это можно сделать и автоматизацией, но иногда все же и так нужно)

    Удаление элемента Смарт-процесса

    Вы пишите про удаление (delete), а сами используете операцию "изменения" (update).


    1. MatasDragonV Автор
      30.05.2023 14:02
      -1

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

      "Неограниченное количество" на момент написания комментария составляет 64 смарт-процесса и не больше.

      Просьба предоставить ссылку на официальную документацию либо код ядра системы, устанавливающий данное ограничение.

      В настоящий момент времени фабрики для старых сущностей (Лид, Сделка, Контакт, Компания) работают в экспериментальном режиме и не смотря на то, что на текущий момент существует возможность работать с ними через фабрики, обратиться в техподдержку с ошибками по такой работе вряд ли получиться.

      В экспериментальном режиме но работает. С тем же успехом некоторое время назад были "окрики" что D7 это экспериментальный режим и писать про него не стоит - используйте CIBlockElement::GetList и будет вам счастье :). Цель статьи - дать начинающему разработчику базовое понимание инструментов. Поэтому намеренно разобраны разные способы. А уже что запускает процессы а что не запускает, разработчик должен либо дойти сам, либо получить эти знания на соответствующих курсах. Если описывать в рамках обзорной статьи все эти нюансы, обработки результатов, каик-то еще "навесы" и взаимосвязи - она превратится в "Войну и Мир". Так что на мой взгляд замечание сильно субъективное.

      Нет, не приобретает и так как вы делаете вообще делать не стоит. Ваш код будет выглядеть например так

      Я считаю, что когда критикую чей-то подход, должен дать максимально развернутый и аргументированный ответ почему так "вообще не стоит делать". Видимо у вас подход другой. Жаль. К сожалению на необоснованную аргументами критику мне ответить нечем)

      Смотря что вы вкладываете в понятие кастомизировать.

      Все верно. Это ваше личное мнение а не ошибка. По факту даже изменение пользователя это уже влияние на процесс сохранения. Остальные подходы именно в рамках статьи разбирать не планировалось, опять же чтобы не превращать ее в "Войну и Мир".


      1. gromdron
        30.05.2023 14:02
        +2

        Я хочу чтобы моя позиция была максимально корректно изложена, поэтому несколько тезисов перед прочтением:

        1. Статья про что-то что ранее не описывалось - это ок.

        2. Статья про технологические подходы - это ок.

        3. Статья с примерами плохого кода и описанием почему они плохие - это ок.

        4. Статья с рекламными вставками аля "почему плохо" или "можно ли иначе" узнаете на курсах - это тоже ок.

        5. Я не против нового api и сам его использую, но я знаю его ограничения и я сам (без помощи техподдержки) смогу его отдебажить в случае проблем.

        Но писать статью где показывать плохие подходы, а потом не говорить что они плохие, ссылаться на "разработчик должен ... дойти сам" и тут же говорить про "начинающего разработчика" (в рамках образовательного курса), заявлять заведомо ложную информацию (про бесконечное количество) - это НЕ ок.

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

        Почему смарт-процессов может быть только 64?
        Исторически идентификаторы типов сущностей (entity type id) задаются константами класса CCrmOwnerType и именно он отвечает за валидацию этих типов.
        Если мы откроем класс CCrmOwnerType мы увидим у константы: DynamicTypeStart = 128 и DynamicTypeEnd = 192 они используются как границы (меньшая и большая) в проверке методом isPossibleDynamicTypeId. Т.е. если это смарт-процесс должен вернуться true и в случае использования числа большего чем это значение - вернется false. Соответственно смарт-процесс должен иметь entity type id в пределах этих чисел. Об этом говорил разработчик года 2 назад (точно не помню, у него было пара выступлений), но ссылку на вебинар сейчас не найду.

        Почему я говорю об экспериментальности?

        На странице документации указано что часть сущностей (на которые я ссылаюсь) все-таки доступна, но там так же сказано что для сущности Компания поддерживается только режим чтения. И вроде бы можно было бы на этом остановиться, но если мы провалимся в CCrmDeal::Add (или любой другой метод), то можно увидеть следующий фрагмент кода:

        if ($this->isUseOperation())
        {
        	return $this->getCompatibilityAdapter()->performAdd($arFields, $options);
        }
        

        Отсюда можно сделать вывод, что в будущем код CCrmDeal::Add будет использовать тот же механизм, но нас интересует метод isUseOperation.
        Если вы посмотрите что он возвращает у вас на рабочей установке, то скорее всего увидите false (если вы найдете уже следующее видео от Антона (разработчика), то он там как раз говорит что можно, но на свой страх и риск). Т.е. этот механизм как бы есть, но сам битрикс в коробке его не активирует. По какой причине - не ясно. Возможно они не уверены в его корректной работе, возможно оно не стабилизировано или какие-то другие причины - сейчас не важно.

        Ответвление на ваш выпад про D7

        С тем же успехом некоторое время назад были "окрики" что D7 это экспериментальный режим и писать про него не стоит - используйте CIBlockElement::GetList и будет вам счастье :)

        Раз уж вы все новое api называете d7 (хотя новое название подкапотного фреймворка нельзя отнести к api отдельно взятого модуля) и сами затронули тему про CIblockElement, то я вам так скажу: на текущий момент ORM для инфоблоков не покрывает всех возможностей которые предоставляют старые методы и об этом пишут в документации, если не верите попробуйте поискать по SECTION_GLOBAL_ACTIVE или отфильтровать с учетом прав доступа, и тут ссылаться на "начинающий разработчик сам догадается" уже не профессионально.
        Но да ладно, CIBlockElement::GetList затронули вы и в статье про него речь не идет, так что вернемся к обсуждению.

        Критика вашего подхода работы со смарт-процессами через Datamanager

        Чтобы не потерялось в памяти, мы рассматриваем ваш код по "изменению нескольких полей за одну операцию":

        use Bitrix\Crm\Service\Container;
        
        $factory = Container::getInstance()->getFactory($entityTypeId);
        
        $class = $factory->getDataClass();
        
         $saveResult = $class::update($id, $arUpdate);
        

        Рассмотрим код со стороны идеологии нового ядра.
        Если мы обратимся к документации то увидим ряд недостатков старого ядра (здесь речь не про d7, а про старое api модуля построенное на оперирование "массивом"), а статья об операциях расскажет нам что любое действие над смарт-процессами это не просто какое-то действие, а набор действий.

        И что же вы предлагаете в данном случае?
        Выполнить низкоуровневую операцию (фактически очень легкую обертку над SQL) для того чтобы записать исключительно данные обьекта. А какие последствия такого выполнения?

        Заметили противоречие предыдущему тезису про CIblockElement?

        1. При выполнении обновления не будут пересчитаны права. Если менялся ответственный, то новый ответственный при определенных обстоятельствах не увидит элемента.

        2. Не будут запущены бизнес-процессы и автоматизации, а значит часть бизнес-логики может не отработать

        3. Не будут выполнены действия по операциям, а значит часть клиентской заложенной битриксом логики останется за бортом.

        4. Не будут провалидированы системные поля, а значит ничего не помешает вам записать неконсистентные данные (например направление одно, а статус от другого или поменять birthday sort в обход birthday).

        5. Элемент не будет проиндексирован

        6. Продолжать можно еще долго...

        Я уже не говорю о PARENT полях... Теперь я надеюсь не нужно пояснять почему CUD операции не должны использоваться?

        Двинемся дальше и рассмотрим методsave ($item->save()), в котором мы обнаружим что он по факту является оберткой над EntityObject::save и выполняет те же самые add/update, которые как мы уже выяснили не выполняют много важных бизнес-функций.

        Новое api - объектное и все строится от \Bitrix\Crm\Item, а вы не смотря на то что упрекаете меня "старым ядром" все равно сами на него же и опираетесь предлагая вернуться к массиву.

        Вы сами указываете что цель статья "дать начинающему разработчику базовое понимание инструментов" и что вы не хотите писать "Войну и Мир", так почему вместо того чтобы хорошо рассмотреть один единственный способ работы с смарт-процессами (работу через операции) вы показываете несколько способов которые изначально имеют ограничения? И почему вы ничего об ограничениях них не говорите? Ведь именно операция - это тот самый базовый инструмент по изменению.


        1. MatasDragonV Автор
          30.05.2023 14:02

          Спасибо за развернутый ответ. Я никого никакими ядрами не упрекаю. Вы сами упрекнули меня что:

          В настоящий момент времени фабрики для старых сущностей (Лид, Сделка, Контакт, Компания) работают в экспериментальном режиме и не смотря на то, что на текущий момент существует возможность работать с ними через фабрики, обратиться в техподдержку с ошибками по такой работе вряд ли получиться.

          Потому подобный ответ и получили. И далее:
          Но писать статью где показывать плохие подходы, а потом не говорить что они плохие, ссылаться на "разработчик должен ... дойти сам" и тут же говорить про "начинающего разработчика" (в рамках образовательного курса), заявлять заведомо ложную информацию (про бесконечное количество) - это НЕ ок.

          Про не бесконечное количество, убедили, подкорректировал статью, спасибо. Но в дальнейших ваших выкладках в рамках темы и назначения статьи никакого смысла не вижу. В статье разбирались возможные способы оперирования смарт-процессами. И опять же если перейти в сухой остаток вашего разбора, он сводится к тому что:

          1. При выполнении обновления не будут пересчитаны права. Если менялся ответственный, то новый ответственный при определенных обстоятельствах не увидит элемента.

          2. Не будут запущены бизнес-процессы и автоматизации, а значит часть бизнес-логики может не отработать

          3. Не будут выполнены действия по операциям, а значит часть клиентской заложенной битриксом логики останется за бортом.

          4. Не будут провалидированы системные поля, а значит ничего не помешает вам записать неконсистентные данные (например направление одно, а статус от другого или поменять birthday sort в обход birthday).

          5. Элемент не будет проиндексирован

          6. Продолжать можно еще долго...

          Я уже указывал выше что в статье мы разбираем все способы оперирования элементами без оглядки на внешние действия. Это мини туториал который позволит в качестве быстрого старта работать с элементами, а не подробная статья "Полное API Смарт-процессов". И поэтому показываю все способы, в том числе "неправильные" по вашему мнению. Хотя на мой взгляд в любой разработке нет понятия "неправильно", есть "оптимально" и "не оптимально". А "неправильно" - код в ядре править. Так как применение любых методов имеет как достоинства так и недостатки.

          Причем сами же это указываете:

           так почему вместо того чтобы хорошо рассмотреть один единственный способ работы с смарт-процессами (работу через операции) вы показываете несколько способов которые изначально имеют ограничения

          потому и указываю несколько потому что они существуют и про них нужно упомянуть.

          Также про ваши доводы

           на текущий момент ORM для инфоблоков не покрывает всех возможностей которые предоставляют старые методы и об этом пишут в документации

          для описанных случаев имеют место быть. Но мне очень интересно как вы будете работать со Смарт-процессами через старое АПИ. Не приведете пример? И как вообще описанные случаи относятся к теме статьи (Смарт-процессы). Честно больше похоже на самопиар чем на аргументацию, но в этом плане Хабр вам судья).

          4 Абзаца про экспериментальность и D7 вообще никакого отношения к статье не имеют, показали что матчасть знаете, молодец, вот только с какой целью, непонятно. Как уже указал выше, вы сами меня упрекнули в использовании экспериментальных методов.

          В общем из нескольких абзацев вашего текста суть можно ужать:
          1) Процессов может быть на текущий момент 64 - я с этим согласен. Но это НА ТЕКУЩИЙ МОМЕНТ. И по НЕОФИЦИАЛЬНОЙ информации. Что будет завтра никто не знает. За замечание благодарю.
          2) Про удаление - также благодарю, механическая ошибка.
          3) А вот то что элемент обновляется а связи нет и это ой боже как плохо. Это спорно и то что это "плохо" - я не согласен. Не оптимально - да, чтобы все связи обновились нужно дополнительные приседания делать - да. Но это не "неправильно".


          1. gromdron
            30.05.2023 14:02

            Но мне очень интересно как вы будут работать со Смарт-процессами через старое АПИ. Не приведете пример?

            Нет никакого старого api при работе со смарт-процессами, есть низкоуровневое api (использование datamanager). Есть старое API по работе со сделками/контактами/компаниями/лидами и новое api для crm. Не надо путать одно и другое.


            Вы в вашей статье подаете метод $class::update как единственный способ по обновлению нескольких полей за одну операцию - это ошибка. Нет, если бы вы рассказали про обновление нескольких полей через массив используя compatible-функцию вопросов бы не было, но вы полезли в низкоуровневый update.

            Я уже указывал выше что в статье мы разбираем все способы оперирования элементами без оглядки на внешние действия.

            Вы не написали в статье что рассматриваете все способы (ни одного слова), но вы явно написали что рассматриваете "Базовые операции" - в заголовке статьи. Низкоуровневый update я никак не могут называть "базовым" методом. Отсюда считаю что это - ошибка.

            Я не думаю что вы создаете задачи через internal tasktable add и не думаю что вы обновляете рабочие группы через workgrouptable, так почему здесь вы это допускаете?

            Честно больше похоже на самопиар

            Если честно - ваша статья больше похоже на "мне сказали написать, ну вот и написал" или "напишу что бы было". Мне не нужен пиар - кто захочет что-то найти по битриксу и так меня найдет. Здесь я выступаю в качестве noname с одной единственной целью - если вы хотите доносить реальные знания и наносить пользу сообществу разработчиков Битрикс24 - вы должны по крайней мере не наносить вред.

            История из жизни. Сегодня (какое крутое совпадение) - я с коллегой разбирал случай - один из разработчиков использовал подход с $item->save(), а нам вернули задачу с ошибкой - элемент не ищется в фильтре по свойству с типом адрес. Проблема была в том, что поисковый индекс обновляется через операцию (либо кастомным кодом) и когда он выполнил $item->save() элемент добавился, а поиск не обновился. Пришлось переписывать решение и дописывать отдельный механизм индексации существующих элементов. Это был проиграммист с опытом работы, который почитал документацию, а тут вы выдаете это в статье за чистую монету без примечаний да еще и для новичков

            Я не могу расценить эту статью за нанесение пользы, ведь после нее будут еще люди которые пойдут в техническую поддержку, на форум, в чаты по битрикс24 с невнятным описанием "битрикс г...но потому что не ищется".

            А вот то что элемент обновляется а связи нет и это ой боже как плохо. Это спорно и то что это "плохо" - я не согласен. Не оптимально - да, чтобы все связи обновились нужно дополнительные приседания делать - да. Но это не "неправильно".

            Плохо ли, что элемент обновляется, а связи нет? Нет, это не плохо.
            Но подавать это как "базовый метод", не написав про ограничения и последствия что будет после этого - это плохо.


  1. MatasDragonV Автор
    30.05.2023 14:02

    Нет никакого старого api при работе со смарт-процессами, есть низкоуровневое api (использование datamanager). Есть старое API по работе со сделками/контактами/компаниями/лидами и новое api для crm. Не надо путать одно и другое.
    Ну так по вашим прошлым выражениям новое апи же экспериментальное и его использовать ой как плохо. Сами себе противоречите.

    Вы в вашей статье подаете метод $class::update как единственный способ по обновлению нескольких полей за одну операцию - это ошибка. Нет, если бы вы рассказали про обновление нескольких полей через массив используя compatible-функцию вопросов бы не было, но вы полезли в низкоуровневый update.

    Я нигде не указывал что это "единственный способ". Про "единственный правильный способ" писали только вы. Не нужно смешивать ваши домыслы и убеждения с моими.
    Вы не написали в статье что рассматриваете все способы (ни одного слова), но вы явно написали что рассматриваете "Базовые операции" - в заголовке статьи. Низкоуровневый update я никак не могут называть "базовым" методом. Отсюда считаю что это - ошибка.

    В моем понимании базовые операции - операции позволяющие производить базовые действия с элементами Смарт-процессов. А это создание, изменение и удаление. Без учета связей с другими элементами. То что вы закладываете в понятие "базовый" какой-то дополнительный сакральный смысл - ваше личное дело.
    Я не могу расценить эту статью за нанесение пользы, ведь после нее будут еще люди которые пойдут в техническую поддержку, на форум, в чаты по битрикс24 с невнятным описанием "битрикс г...но потому что не ищется".

    Если вы на подобной операции обожглись и "получили нагоняй" от заказчика или работодателя, это также ваши личные проблемы. И винить статью в них по моему излишне.

    Плохо ли, что элемент обновляется, а связи нет? Нет, это не плохо.Но подавать это как "базовый метод", не написав про ограничения и последствия что будет после этого - это плохо.

    Посмотрите пожалуйста в толковом словаре смысл слова "базовый". Все встанет на свои места.

    Если честно - ваша статья больше похоже на "мне сказали написать, ну вот и написал" или "напишу что бы было". Мне не нужен пиар - кто захочет что-то найти по битриксу и так меня найдет. Здесь я выступаю в качестве noname с одной единственной целью - если вы хотите доносить реальные знания и наносить пользу сообществу разработчиков Битрикс24 - вы должны по крайней мере не наносить вред.

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

    Если вкратце, хотели блеснуть умом, блеснули, вот только с каждым новым сообщением закапываете себя больше. Далее в данных дебатах участвовать смысла не вижу, все равно каждый из нас останется при своем мнении. Не хворать вам!


  1. Masas
    30.05.2023 14:02

    Почитал статью и обсуждения в комментариях. Я считаю, что "Базовые операции" (низкоуровневые) и корректные подходы работы со смартами (о которых говорит gromdron) стоит рассматривать отдельно.

    У меня был опыт работы с проектом, где был применён подход автора статьи и пришлось очень многое переделывать, так как весь функционал свёлся к работе со смартами как с обычными сущностями (datamanager) и львиную долю штатных возможностей реализовали сами. Появляется вопрос, "а тогда зачем?".

    P.S. учить абы как потому что ни кто больше не учит - не самое здравое решение.