Не так давно мы закончили писать первую версию документации по смарт-процессам и новому API CRM. Спасибо Роберту и его команде за оперативную публикацию.
Документация тут -
Если её внимательно прочитать (а ещё лучше - ознакомиться с исходным кодом), то станет понятно, что у разработчиков появляется возможность внедриться очень глубоко в API "малой кровью" (без модификации ядра). Мы почти не ставили final у классов и методов, только местами.
Однако наличие этой возможности не значит, что ей необходимо очень активно пользоваться.
Как вы знаете, мы поддерживаем обратную совместимость. Но цена этой поддержки - довольно высока. Это в буквальном смысле сковывает нам руки - нам всё время приходится держать в голове необходимость поддержания совместимости, рефакторить сильно нельзя и т.д. Код становится "закостенелым" и буквально превращается в легаси с момента выхода первой его версии.
Теперь, когда у разработчиков есть возможность наследовать классы продукта, это становится ещё сложнее. Т.к. по-хорошему, мы не можем менять даже сигнатуру protected методов.
В связи с этим большая просьба - при наследовании классов придерживайтесь рекомендаций, изложенных на этой странице
Здесь я изложу их ещё раз немного другими словами
1. Не надо наследовать стандартные классы без особой необходимости вообще. Делайте это только в крайнем случае и когда вы полностью отдаете себе отчет, как и что вы делаете
2. Не надо использовать / наследовать те классы, которые в документации помечены соответствующим образом (ParentFieldManager и другие).
3. Если вы наследуете класс, ни в коем случае не меняйте сигнатуру методов добавлением новых аргументов / изменением типов возвращаемых значений и т.д. Если надо передать какие-то дополнительные данные, сделайте отдельный метод для этого
4. Не стоит слишком полагаться на структуру массивов внутри классов. При использовании делайте проверки.
5. Даже следуя этим рекомендациям можно столкнуться с тем, что после установки обновления что-то отвалится из-за каких-то изменений. Пишите тесты, тестируйте обновления не на продакшн-окружении, используйте фича-флаги.
Если после ознакомления с кодом или документацией вам что-то не понравилось - не стесняйтесь писать.
По поводу нового API для старых сущностей - будет, но не сразу. Не так давно мы сделали возможность читать данные о лидах, сделках, контактах и компаниях (выйдет в районе crm 21.800.0). Позже добавим возможность и делать изменения через новое API.
По поводу реста - доделываем прямо сейчас, будет классно.
Вопрос: когда можно ожидать инструмент импорта-экспорта элементов СП? 👀
В crm 21.800.0 выйдет рест. Возможно, кто-то запилит приложение с экспортом/импортом
Остаётся надеяться, что кто-нибудь из авторов имеющихся импортилок/экспортилок CRM-сущностей допилят свои детища до СП. 👀
А как обстоят дела с подтягиванием данных из СП в Аналитику и конструктор Отчётов? Есть надежда? 🤔
И ещё одна хотела —
С конструктором отчетов - пока в планах не стоит. Может быть когда-нибудь и появится.
Пробуем на функционале СмП решить некоторые свои задачи учета, возникла такая потребность.
Вводные:
к СмП1 (перечень) привязан дочерний СмП2.
СмП1 не имеет привязки к клиенту.
СмП2 имеет привязку к клиенту плюс некоторые пользовательские поля.
Пользовательские поля СмП2 меняются в зависимости от продвижения сделки по клиенту, в сделке есть поле тип СмП1.
Задача: Обработать элемент СмП2 связанный с СмП1 и с клиентом
Вариант1: через getItem накладываем фильтр по клиентскому полю и проверяем связь СмП1 с СмП2
Вариант2: через getChildElements получаем дочерние элементы СмП1 и проверяем тип дочернего элемента = СмП2 и Клиент = Клиент
Вариант3: у СмП2 делаем пользовательское поле тип СмП1 и по нему вручную пишем в RelationManager, затем через getItem фильтруем по клиентскому полю и пользовательскому полю с Смп1
Все варианты некрасивые)
А вот getChildElements с фильтром красиво.
Пока что единственный рабочий вариант - это через getChildElements получить список идентификаторов и засунуть их в фильтр.
Это универсальное апи, оно очень простое, для решения узкой задачи.
Если вы заранее знаете тип связи (вплоть до ид типа), то воспользуйтесь прямым обращением к таблице \Bitrix\Crm\Relation\EntityRelationTable
Обнаглею и задам следующий вопрос, продублирую
При интерактивном добавлении дочернего смарт-процесса(СмП), на его форме родительский элемент виден.
Но через бизнес-процессы доступа к нему нет, более того при попытке поискать через relationmanager получаем нулевой результат.
Видимо в EntityRelationTable данные пишутся уже после вызова всех обработчиков.
Нужно либо в шаблон БП "при создании" передавать идентифер родительского объекта, либо в EntityRelationTable писать до вызова пользовательского БП.
1. Сейчас сохранение связей для смарт-процессов осуществляется после выполнения Operation, и на уровне Item\Operation к значениям полей с родителями никак не добраться. Это поведение будет исправлено (в Item появится нативная поддержка таких полей, в Factory::getFieldsInfo будут данные о полях с родителями).
2. Когда будет исправлен пункт 1 появится возможность работать с этими полями и в БП (может быть не сразу, как коллеги запилят и выпустят).
Пока что да, родительские поля пристегнуты немного сбоку, ещё доделываем
Ещё было бы неплохо иметь возможность пристегивать шаблон БП при удалении элемента.
Смарт-процессы как раз удобны своей связанностью, но при этом при удалении родительского или дочернего элемента нет штатной возможности обработать связанные элементы.
Связанный элемент теряет связь и даже не знает об этом ничего.
Можно конечно подвесить БП с ожиданием и проверкой наличия связи, но это неправильно с точки зрения нагрузки на сервер.
Есть подобное в планах или какие-то другие варианты решения?
Скоро выйдет рест, там можно будет подписаться на событие удаление элемента смарт-процесса любого типа и внутри делать нужные вам проверки.
Кстати, в
У меня вопрос по примеру "сделать
Все хорошо, если назначить полю атрибут \CCrmFieldInfoAttr::ReadOnly поле при сохранении не меняется, но зачем для такого поля в интерфейсе вообще давать возможность выбора? Это только путает пользователя.
В идеале такое поле должно отображаться на форме, но не иметь диалога выбора, только для чтения же.
Мне кажется это поведение нужно исправить.
Пользовательские поля в карточке отрисовываются "особым" образом, и в их представлении нет такого понятия, как "только для чтения".
По поводу элемента. С одной из версий crm во всех ACTION_AFTER_SAVE будет возможность получить инстанс Item до сохранения через \Bitrix\Crm\Service\Operation\Action::getItemBeforeSave(). Там будет id
Будет ли работать подписка? У меня не получается.
BX.addCustomEvent("onCrmDynamicItemAdd", BX.delegate(function(params){
console.log('onCrmDynamicItemAdd params',params);
}, this));
У меня CRM-форма, которая создает элемент смарт-процесса. Нужно получить id и его модифицировать (добавить товары и проч).
Ситуация следующая:
Сотрудник-Клиент ставит задачу на выполнение услуги, далее руководитель или менеджер двигают эту задачу по стадиям.
При этом Сотрудник-Клиент должен видеть (в идеале на некоторых стадиях вносить правки или хотя бы комментировать) движение его задачи.
Сейчас приходится костылить и постановщика принудительно записывать в наблюдатели.
Я говорю про коробку, обновления установлены актуальные.
Вариант с наблюдателями, мне кажется, вполне приемлем.
задачи".Рассмотрим следующую ситуацию:
Сотрудник компании (бухгалтер) нуждается в услуге по перевозке и подписи своих документов.
Движение из офиса1 в офис2, при этом в офисе2 надо поставить визу на документы и вернуть в офис1, дополненные другой пачкой. На выходе должны получить документ с историей согласования, номером регистрации в офисе2 и т.д.
Тут получаем стадии:
- запрос на перевозку,
- в пути в офис2,
- зарегистрировано в канцелярии офиса2,
- документы на подписи,
- в очереди на перевозку в офис1,
- в пути в офис1,
- закрыта.
Как быть бухгалтеру? Он должен видеть полное движение своих документов, где и на какой стадии, что застряло, если что позвонить и поторопить.RPA не подходит, процитирую Вас же "RPA это про процесс, который отработал и забыли, а СП это про документ", может не совсем дословно..
Это и не про документооборот, и не про задачу, это отлично складывается в СП со своими БП, стадии, связанными сущностями (по движению документов можно эскалировать создание других СП, задач, событий в календаре и т.д.)
Расширение ролей в смарт-процессах произойдёт только с реализацией новой схемы прав во всей CRM. Когда-нибудь это произойдет.
В общем, ждем. Было бы круто это получить совместно с множественными ответственными.
Можно какое-то пример кода для api?
В БП доступ появится вместе с релизом или...
Например, в новом апи
$item->set('PARENT_ID_2', 10);
$item->get('PARENT_ID_2');
в новом апи в $arFields можно читать / передавать поля вида PAREN_ID_...
Не работает.
И по идее getFieldsInfo должен что-то знать про это поле, правильно?
Какая версия crm стоит?
В методе \Bitrix\Crm\Service\Factory::getFieldsInfo() вызывается \Bitrix\Crm\Service\ParentFieldManager::getParentFieldsInfo(), который отдает родительские поля.
Проверьте, что у вас родитель и потомок не перепутаны местами.
Ну и можно дернуть метод \Bitrix\Crm\Service\ParentFieldManager::getParentFieldsInfo(), посмотреть, что отдает
array(1) { ["PARENT_ID_133"]=> array(3) { ["TYPE"]=> string(10) "crm_entity" ["SETTINGS"]=> array(1) { ["parentEntityTypeId"]=> int(133) } ["TITLE"]=> string(16) "Задачи" } }
Если смотреть ответ метода getParentFieldsInfo, то код выше и не должен ничего возращать. Т.к. у вас есть родительское поле PARENT_ID_133, а не PARENT_ID_161.
Entity has no `PARENT_ID_161` field.
Entity has no `PARENT_ID_133` field.
После обновления появилось новое активити "Информация о привязанном элементе" это способ доступа к обещанному родительскому полю?
Все хорошо, но активити работает через getParentElements, но в момент создания элемента связи ещё не прописаны и активити в БП при создании ничего не возвращает.
В коробке не работает.
Информация о привязанном элементе - в БП при создании элемента в доп.результате 0
[$entityTypeId, $entityId] = CCrmBizProcHelper::resolveEntityId($this->GetDocumentId());
$this->SetVariable("entityTypeId",$entityTypeId);
Что за ситуация, когда он вам понадобился? Шаблон БП жестко привязан к смарт-процессу, поэтому entityTypeId известен разработчику и в конкретном шаблоне это как константа.
Миграция однотипных шаблонов между сП?
В БП webhook дергает php-код на внешнем сервере, который, после необходимых операций записывает результат в текущий документ смарт-процесса (crm.item.update).
При вызове в webhook передаю entityTypeId смарт-процесса и id документа смарт-процесса. Думал что может есть какая-то языковая конструкция (типа как ID бизнес-процесса {=Workflow:ID})
Результат выполнения передается в переменную БП entityTypeId вот этим кодом:
$this->SetVariable("entityTypeId",$entityTypeId);
Посмотрите
Через дебаг определил название таблицы
Но стандартный метод навешивания не работает
Мне нужно проверить и отфильтровать некоторые поля на изменение - можно конечно скопировать компонент crm.item.details и изменить метод saveAction - но хочется сделать "правильно"
не хватает примера как подменить/расширить класс таблицы сущности чтоб переопределить методы onBeforeUpdate или навесить обработчики без переопределения класса
Пример навешивания события на таблет есть вот тут \Bitrix\Crm\Service\Operation::launch() в конце
т е просто "сбросить" значения некоторых поля которые недоступны по моим настройкам на редактирование для определенных пользователей
подскажите dev.1c-bitrix.ru/api_d7/bitrix/crm/customization/index.php
если надо вмешатся в процесс изменения полей (при сохранении)
Я закинул себе в беклог задачу с добавлением событий в старом формате и для элементов смарт-процессов. Но ничего не могу сказать по срокам. Будут новости - напишу ещё заметку, наверное.
только он странно работает, поле в карточке все равно можно отредактировать хотя оно и не сохранится
и этот способ будет работать только для редактирования стандартной карточки документа или везде где производится модификация документа от текущего пользователя (через какие то другие компоненты или api смарт процессов)?
В этом методе лучше добавлять свои Operation\Action, которые будут что-то менять во время выполнения
Если я правильно понял логику, то при изменении основного поля очищаются зависимые поля?
В интерфейсе отображаемые поля не всегда соответствуют полям в базе. Например, поле "Клиент" - это "Компания" + "Коллекция контактов".
В настройках задается обязательность поля "Клиент", а через этот метод проверяется, какие на самом деле надо проверять обязательные поля.
Будут множественные отвественные?))
Немного нестандартный вопрос.
Есть задача сделать КП с несколькими(множеством) цен за разные объемы покупки, т.е. нужно реализовать генератор документов, чтобы получить примерно такую таблицу
Наименование / Цена за 10шт / Цена за 100шт / Цена за 1000шт
Товар1 / 3р / / 2р
Товар2 / 5р / 4р /
т.е. в товары предложения можно добавить строки:
Товар1 10шт 3р
Товар1 1000шт 2р
Товар2 10шт 5р
Товар2 1000шт 4р
Кастомизацией провайдера планирую переопределять Products - повторяющиеся строки удалять, а цены и количество из них писать в первую строку, например, в пользовательское поле ProductsProductProperty57 или в собственное поле для плейсхолдера Products
В итоге получать типа такого:
Товар1 ProductsProductProperty55 - 10шт, ProductsProductProperty56 - 100шт, ProductsProductProperty57 - 1000шт, ProductsProductProperty58 - 3р, ProductsProductProperty59 - пусто, ProductsProductProperty60 - 2р
Товар2 ProductsProductProperty55 - 10шт, ProductsProductProperty56 - 100шт, ProductsProductProperty57 - 1000шт, ProductsProductProperty58 - 5р, ProductsProductProperty59 - 4р, ProductsProductProperty60 - пусто
Собственно проблема в том, что количество колонок может быть произвольное, в одном КП две колонки, в другом три или 4ре, а может быть даже 5.
Заранее закладывать максимальное количество колонок, значит в КП где их меньше будут некрасивые пустые колонки.
Сделать меньшее количество колонок, рано или поздно потребуется на одну больше.
В идеале вложенный цикл по колонкам нужен, но насколько я понимаю шаблоны такого не поддерживают.
Может быть есть какая-то более элегантная реализация?
Генератор документов не поддерживает сложную работу с таблицами - объединение колонок, произвольное количесто колонок и т.д.
Чтобы решить эту задачу, придется переопределить парсер \Bitrix\DocumentGenerator\Body\DocxXml, и в нем сделать полностью свой механизм формирования сложных таблиц на осное ваших данных. Провайдера тоже надо будет добавить, который будет вам данные готовить в нужном виде.
Был у меня небольшой подход к такой задаче, в конце файла \Bitrix\DocumentGenerator\Body\DocxXml есть несколько закоментированных методов, можно туда глянуть.
Для чего изменили генератор STATUS_ID?
Раннее он был по шаблону
Сейчас
Если создавать несколько направлений в рамках одного СП, то можно легко встраивать свои проверки перед сохранением в кастомной фабрике, главное условие - создавать стадии в том же порядке.
Сейчас приходится лезть в БД и напрямую там исправлять.
А еще это всё помножим на отсутствие миграции с тестовой машины в рабочую, вот и получаем много монотонной работы на ровном месте.
У меня есть СП с 30 воронками, в каждой по 3-6 кастомных стадий (помимо дефолтных)
Сделано это было по запросу разработчиков (лично мне не мешало).
Запрос был в том, что при удалении и создании новой стадии код этих стадий совпадал. И это могло мешать при интеграциях.
Мы понимаем, что это могло поломать какие-то другие сценарии.
Для решения проблемы есть несколько способов
1. Создавать стадии через апи, задавая свои коды
2. Подписаться на соответствующее событие onBeforeAdd таблета и там делать замену на то, что нужно
На сейчас оба варианта не быстрее, чем в базе поменять
Если вдруг появится желание и время, то было бы круто рядом с кнопкой заливки цветом заиметь вторую кнопку с заменой кода на свой - это упростило бы жизнь простым пользователям, кто в код и базу не может влезть.
Столкнулась с проблемой при работе со смарт-процессами в разных Б24. Прошу вашей помощи.
Есть выгрузка из 1С документов в смарт-процесс облачного Б24. Все замечательно. При выгрузке выполняется связь элемента смарт-процесса с сущностью Сделки. ИД сделки записывается в поле parentID2. Связи появляются, все работает.
При выполнении этого же обмена с коробочной версией Б24 столкнулась с тем, что поле parentID* не появляется при указании связи в смарт-процессе.
Версия коробочной битрикс 21.900
Имеется задача по смарт-процессу, чтобы при смене стадии назад или смене на определенную стадию смарт-процесс возвращался обратно на стадию. То есть сделать запрет на передвижение смарт-процесса назад, разрешить только вперед.
Не знаю, как реализовать для смарт-процесса подобную логику. Как я понимаю, надо делать через новое API так, как там имеются функции для смарт-процессов. Мне источники и примеры куда копать, чтобы реализовать данную логику. И подскажите реально реализовать подобную логику, чтобы нельзя было назад двигать смарт-процесс?
Б24 коробка.
Имеется код для сделок:
Если подходит, то данный код также пишется в init, как в события?
Исходя из примеров
Ловлю ошибку на детальной странице счета