Генератор документов - феррари на которой можно ездить только вокруг дома, Новый модуль получился хорошим но не предназначен для использования разработчиками.
Доброго дня Оставлю тут предупреждение для тех, кто решит делать сложный проект через REST API на облаке, используя конструкции, подобные "Таблица внутри повторяющихся блоков", которые описаны в https://dev.1c-bitrix.ru/rest_help/documentgenerator/example.php Там есть не описанные ограничения! Я о них не знал и пожалел. Обработка запроса генерации документов, идущего на облачный сервер Битрикс, очень тяжелая. Чем больше в шаблоне динамических данных, тем она тяжелее. В нашем проекте был полностью динамически формируемый документ с высокой вариативностью, из-за чего пришлось все делать такими конструкциями. И примерно при 3 конструкциях "Таблица внутри повторяющихся блоков", каждая из которых содержала примерно 3 таблицы (это было всего 5 страниц в текстовом документе), сервер Битрикса стал не справляться и выдавать ошибку INTERNAL_SERVER_ERROR, документ при этом не создается вообще. То есть именно с обработкой этих запросов могут быть большие задержки, и можно неожиданно упереться в неописанное ограничение при относительно небольшом объеме документа. Решения у данной проблемы нет, кроме как использовать для генерации документов какую-то свою коробку вместо облака (там нет этих ограничений). В ТП заявка по проблеме есть, под номером 161135 "Облака при обработке шаблона документа (Maximum execution time exceeded)". Сервер Битрикса начинает отклонять запросы, когда не может выполнить их за 60 секунд. Через curl_getinfo можно отслеживать этот параметр для текущего запроса, чтобы понимать, где находится допустимая граница. Пример логов отклоненного запроса:
Не запускаются роботы той стадии, на которую происходит перемещение. Это нормальная работа, так и должно быть. Но есть ли способ как-то запустить все роботы стадии, как при ручном перемещении сущности? Иногда бывает, что на стадии настроили длинную цепочку роботов, и каждый из них прописывать отдельно в код перевода на эту стадию автоматикой не хотелось бы. Может, нужно передать в запрос какие-то доп. параметры, или есть отдельная функция для запуска всех роботов по лиду/сделке ?
И еще один момент непонятен Синхронизирую смарт-процесс с 1С, сущность Реализация (акты, накладные, УПД) На вкладке сопоставления полей для перехода документа Б24 -> 1C можно установить дату документа Указываю для даты - источник "Из пользовательского поля", значение - пользовательское поле смарта в Б24 Со стороны Б24 это поле типа "дата" Далее создаю элемент смарта в Б24, заполняю это поле сегодняшней датой, синхронизирую, получаю ошибку "Дата -- Дата документа должна быть не ранее 2000 года" Вероятно, разный формат дат в полях и там 1970 пришел Как правильно передать дату тогда? Может, в строке собрать значение другого формата перед синхронизацией? Или использовать поле дата/время?
Благодарю за ответ При настройке синхронизации заметил одну странность В "настройке отборов и полей" для контактов в открывающемся справа меню можно задать сопоставление полей при выгрузке на портал (например для синхронизации контактов Б24 с контрагентами 1С, или контактов Б24 с контактами 1С) Там выводится список полей контактов в Б24, но только стандартных (белые строки), а все пользовательские поля (бирюзовые строки) попадают туда из компаний, как я понял Может в модуле ошибка где-то? Мы сами не перенастраивали ничего похожего
Андрей Гомзин написал: Добрый день! Подскажите, пожалуйста Пробуем настроить интеграцию 1С и Битрикс-24 с помощью роботов и триггеров Нашли робот "Создание документа на основании", который позволяет создать в 1С новый документ на основании существующего документа из таймлайна сделки. Но как настроить этот робот, чтобы создать документ по данной сделке впервые? Например, автоматически создать счет покупателю по новой сделке, чтобы потом на его основании создавать УПД и т.п. Тогда можно будет настроить работу для менеджеров в Б24 полностью без захода в 1С.
Так только роботами не сделать. Нужно настраивать синхронизацию в режиме реального времени, чтобы на основании сделки создавался заказ. А вот через него можно роботами/триггерами делать УПД. Сложнее, если 1С Бухгалтерия, там синхронизации сделок нет и так сделать не получится.
Поняли, спасибо. У нас как раз Бухгалтерия Попробовал зайти со стороны смарт-процессов, получилось синхронизировать их с УПД (при создании смарта с товарами в 1С все переходит), но столкнулся с проблемой, что в карточке смарт-процесса нет списка расширений сверху (где обычно находится реестр документов и список документов 1С для создания). В настройках Бэкофиса галочки можно проставить только для 4 основных CRM-сущностей, а смартов нет. Также не создается дело в таймлайне элемента смарт-процесса. В итоге все вроде бы создается, но из Битрикса напрямую не открыть. В смарт-процессах видел роботов, но, как я понял из вебинаров, они работают только с делами сущности. Непонятно, как их использовать, если дела не создаются.
Подскажите, можно ли как-то при такой синхронизации добавить меню документов в карточку смарт-процесса (как у сделок и т.п.)? Есть ли способ создавать дела в таймлайне для открытия УПД из смарт-процесса / настройки на них роботов?
И еще такая костыльная идея есть - из сделки создать документ в 1С через Бэкофис, при этом в таймлайн сделки приходит дело, а в смарт-процессе создается новый элемент (приходит из 1С по синхронизации). Далее дело из сделки перемещаем в этот элемент смарта через \CCrmActivity::SaveBindings (битрикс коробка), в итоге получается смарт-УПД с привязанным делом по самому себе. И далее роботами работаем с ним. Такое может сработать?
Добрый день! Подскажите, пожалуйста Пробуем настроить интеграцию 1С и Битрикс-24 с помощью роботов и триггеров Нашли робот "Создание документа на основании", который позволяет создать в 1С новый документ на основании существующего документа из таймлайна сделки. Но как настроить этот робот, чтобы создать документ по данной сделке впервые? Например, автоматически создать счет покупателю по новой сделке, чтобы потом на его основании создавать УПД и т.п. Тогда можно будет настроить работу для менеджеров в Б24 полностью без захода в 1С.
Генератор документов - феррари на которой можно ездить только вокруг дома, Новый модуль получился хорошим но не предназначен для использования разработчиками.
Проверил разные варианты "Контролировать загрузку дубликатов файлов" и правда было включено А по самой проблеме - вероятнее всего, это из-за особенностей поля типа файл именно в сущности смарт-процессов Попробовал через обычный БП заполнить в поле типа "файл" id файла на смарт-процессе и на контакте При этом один и тот же файл в контакте отображается правильной ссылкой типа '.../bitrix/components/bitrix/crm.contact.show/show_file.php?...', а именно в смарт-процессе стоит абсолютный путь То же самое при ручной загрузке файла в поле, только в смартах показывает абсолютый путь Но по почте файл из поля нормально отправляется, а для менеджера вывел через диск и комментарий в таймлайне, так что можно сказать, что решилась проблема Спасибо за помощь
Генератор документов - феррари на которой можно ездить только вокруг дома, Новый модуль получился хорошим но не предназначен для использования разработчиками.
Подскажите, пожалуйста, как нормально сохранить PDF файл, который получили при генерации (пример из документации), в карточку лида / сделки / смарт-процесса и т.п.? Вот, что я делаю: 1)создаю документ по PHP API 2)подписываюсь на событие onDocumentTransformationComplete и ожидаю от него ответа 3)получаю документ
6)файл в поле прикрепляется, и все, вроде бы, отлично НО! При клике на файл в поле он сохраняется без расширения. Он называется просто 'mckgetv1vfbc8i7mpagflirf95lc87tb'. Если скачанному файлу проставить расширение вручную, то есть переименовать в 'mckgetv1vfbc8i7mpagflirf95lc87tb.pdf' - файл открывается. Если рядовой пользователь будет такое скачивать - запутается. Я пробовал много способов это исправить. После формирования массива файла добавлять насильно расширения в элементы массива, переименовывать файл в папке /upload/documentgenerator, сохранять файл на диск к боту, копировать файл в свою папку, создавать массив файла через внешнюю ссылку на скопированный файл, но такое ощущение, что все это лишь передает ссылку на изначальный файл, не создавая его реальной копии. Так, при наведении на поле внутри карточки, всплывает ссылка на скачивание вида 'схема/домен/upload/documentgenerator/3ca/mckgetv1vfbc8i7mpagflirf95lc87tb' И она всегда остается неизменной, и по ней всегда скачивается файл без расширения. Я даже скачал файл к себе на компьютер, прописал расширение, загрузил его назад в поле руками, и... ссылка не поменялась, там снова upload/documentgenerator! Как будто он по содержимому понял, что это тот же самый файл. Остальные файлы при ручной загрузке попадают в upload/main, upload/crm и т.п. Я даже удалил папку documentgenerator/3ca, но ссылка все равно ведет туда и скачивается то же самое. Поэтому прошу помощи - как это нужно сделать по-нормальному? Чтобы из поля скачивался файл сразу с расширением '.pdf'. Спасибо.
Есть задача работать с элементами смарт-процессов через API в коробке Документация вроде имеется, но все как-то по кускам Полдня копался в описании нового ядра и в самом этом ядре, набросал основные методы для себя Возможно, кому-то сэкономит время
Код
//---------------Общие действия для всех запросов---------------
//подключение пролога
require($_SERVER["DOCUMENT_ROOT"]."/bitrix/modules/main/include/prolog_before.php");
//подключение классов / модулей
use Bitrix\Main\Loader;
use Bitrix\Crm\Service;
use Bitrix\Crm\Item;
Loader::includeModule("crm");
$entityTypeId = 181; //задаем id нужного смарт-процесса
$container = Service\Container::getInstance();
$factory = $container->getFactory($entityTypeId);
//---------------Действия с элементами---------------
//получение списка элементов по фильтру
$parameters = array(
'select' => array(), // имена полей, которые необходимо получить в результате
'filter' => array('<ID' => 100), // описание фильтра для WHERE и HAVING
'group' => array(), // явное указание полей, по которым нужно группировать результат
'order' => array(), // параметры сортировки
'limit' => 0, // количество записей
'offset' => 0, // смещение для limit
'runtime' => array(), // динамически определенные поля
);
$allItems = $factory->getItems($parameters);
$rows = array();
foreach ($allItems as $item) {
$rows[] = $item->getCompatibleData(\Bitrix\Main\ORM\Objectify\Values::ALL); //getData - для вида полей "нового API"
}
echo '<pre>'; print_r($rows); echo '</pre>';
//добавление элемента
$data = array(
'TITLE' => 'Новый элемент',
'CATEGORY_ID' => 1,
'STAGE_ID' => 'DT181_1:NEW',
'COMPANY_ID' => 130,
'CONTACT_ID' => 80,
'UF_CRM_1_TEST' => 'testString', //пользовательское поле
);
$item = $factory->createItem($data);
$item->save();
echo $item['id'];
//изменение элемента
$item_id = 7; //id элемента
$data = array(
'TITLE' => 'Измененный элемент',
'STAGE_ID' => 'DT181_1:PREPARATION',
'CONTACT_ID' => 139,
'UF_CRM_1_TEST' => 'updatedString',
);
$item = $factory->getItem($item_id);
$item->setFromCompatibleData($data);
$item->save();
//удаление элемента
$item_id = 7; //id элемента
$item = $factory->getItem($item_id);
$item->delete();
Благодарю, подправил с параметрами По этому посту на хабре сначала и начинал делать, но потом немного дополнил получением последнего ID из прошлого запроса батча и объединением всех батчей в один запрос "Впрочем, таким образом достаточно просто перегрузить сервер, который даже при соблюдении скорости запросов начинает обрывать соединение и уходить в таймауты." - вот это больше всего испугало в параллельности, но как-нибудь попробовать можно будет
Приветствую, коллеги Для внешних приложений, а также для массовой обработки часто требуется выгрузить все имеющиеся сущности на портале (лиды / сделки и т.п.). Однако по умолчанию рест-запросы позволяют получить только 50 сущностей за раз: https://dev.1c-bitrix.ru/rest_help/rest_sum/start.php В итоге, если в базе сотня тысяч лидов, приходится направлять большое число запросов, из-за чего можно столкнуться с ограничениями. Но есть специальный метод, batch, позволяющий объединить запросы пачками по 50 штук: https://dev.1c-bitrix.ru/rest_help/general/batch.php Таким образом, за 1 запрос можно получить уже 2500 сущностей. Но я попробовал объединить batch в batch, и это сработало. Таким образом, можно создать сложный вложенный запрос, которым возможно получить, к примеру, все лиды на портале. Предела вложенностей батчей друг в друга я не нашел, если сущностей более 125 000, просто увеличиваем уровень вложенности.
Такого способа я не видел ни в одном руководстве / форуме, поэтому и возник вопрос - какие могут быть подводные камни у этого способа? Может быть, есть причины, по которым это не используют?
Однако, для формирования батчей нужно изначально знать общее количество сущностей данного типа, для чего нужен один предварительный запрос, на основании которого уже формируется основной запрос. В пределах одного батча можно обращаться к результатам предыдущих запросов, что позволяет использовать параметр start (подсчитывает общее количество и значительно тормозит обработку) только в первом запросе каждого батча, а далее передавать "ID > крайнего ID из прошлого запроса" и start = -1 (отключает подсчет), что ускоряет время обработки. Обратиться к результатам последнего запроса другого батча из пачки я не смог. Что-то вроде $result['batch1']['lead_list50'][49][ID] или $result['batch1']['result']['lead_list50'][49][ID] не работает. Может быть, есть способ это сделать?
Для эксперимента взял портал с примерно 135 000 лидов, их выгрузка с несколькими базовыми полями заняла около 10-15 секунд. Пример кода
Вопрос решен, возможно будет кому-то полезно Права по умолчанию в основном проверяются в модуле CRM
1 способ - авторизация за пользователя Всегда рабочий способ, но минус с точки зрения безопасности Создать пользователя с минимально необходимыми правами, при этом ограничить ему доступ на просмотр всех страниц портала, оставить только права на нужные действия в CRM, время жизни сессии ограничить временем работы скрипта (0.2 минуты к примеру)
Код
$USER ->Authorize(50); //авторизоваться в системе за пользователя
//здесь выполняем необходимые действия
$_SESSION = array(); //выходим из юзера - очищаем данные сессии
2 способ - вызов методов CRM с отключением проверки прав
Андрей Николаев написал: в массив фильтрации добавить CHECK_PERMISSION => 'N' и все.
Попробовали так сделать, но все равно что-то не то При запуске без паузы отрабатывает При запуске с паузой процесс зависает на активити с кодом и дальше не идет, передавая статус "Выполняется" Для теста взяли простой фильтр с получением поля:
Столкнулся с аналогичной проблемой После паузы стоит блок с кодом php Чтение из инфоблока, запись в инфоблок отрабатывают корректно Все, что связано с CRM, например метод CCrmContact::GetListEx для получения списка контактов, не отрабатывает При запуске процесса без паузы делает выборку необходимых контактов, при запуске с паузой - пустой массив Как будто дело в правах доступа, и при прямом запуске отрабатывает с правами запустившего, а после паузы процесс работает как бы уже сам по себе, и не имеет доступа к модулю CRM Как ни извращался, не смог запустить этот метод после паузы
Ну, от безысходности и большой надобности я придумал костыль... Создал в структуре .php файл, из блока активити функцией битрикса QueryGetData кидаю в него get-запрос с нужными параметрами, в этом файле при распознавании запроса логинюсь за пользователя с нужными правами и делаю все, что мне надо Для безопасности можно перед запросом генерировать токен, записывать его в таблицу, передавать в параметре запроса, проверять на принимающей стороне и чистить таблицу
Столкнулся с проблемой - получаю свойство элемента типа HTML/текст, вроде бы все нормально, но при дальнейшем использовании оказывается, что этот текст имеет скрытые переносы строк в случайных местах (где изначально их не было, но битрикс решил, что теперь будут), а в тех местах, где были настоящие переносы - выводится <br> Оказалось, что в данной строке содержатся переносы двух видов 1)Реальные, которые можно увидеть как <\b\r> через echo addcslashes($text, 'A..z'); 2)Случайно возникшие, которые невидимы даже так, но все равно присутствуют в строке Однако при кодировании строки в json, все переносы видны как \r\n, хотя для реальных также дополнительно сохраняется скрытый даже там <br> И при передаче данного массива для дальнейшей работы отправляются в итоге кривые данные
Решил в итоге таким костылем
Код
$text = htmlspecialcharsBack($arFields["~PROPERTY_204_VALUE"]["TEXT"]); //получаем значение и сразу отсекаем часть лишних символов
$text = str_replace('<br>', '~BR~', $text); //временно заменяем невидимый код нужных переносов на что-то видимое
$text = json_encode($text);
$text = str_replace('\r\n', '', $text); //сносим все переносы (и наши, и случайные)
$text = str_replace('~BR~', '\r\n', $text); //проставляем переносы в нужных местах
$text = json_decode($text);
В итоге получилась чистая строка с "совсем невидимыми, но существующими" перносами только в нужных местах
А есть ли способ составить фильтр, если нужно проверить, что какое либо единичное значение НЕ содержится в множественном свойстве? Задача - в инфоблоке есть множественное свойство со списком ID-шников, нужно выбрать те элементы инфоблока, где данный конкретный ID не содержится в этом свойстве
Код
При таком способе задания:
$arFilter = array("IBLOCK_ID"=>90, "!PROPERTY_210"=>$id)
если в свойстве лежит, например, 3 ID, из которых один - исключаемый, то данный элемент попадет в выборку аж 2 раза (по одному на каждое несовпадающее значение), а хотелось бы данный элемент вообще не получать
Конечно, можно получать всю выборку, а потом отсеивать ненужные элементы, но хотелось бы иметь возможность фильтровать сразу
Евгений Жуков написал: Для таких целей есть rest и веб-хуки. И вопросы авторизации и прав там решены. Реализовывать вашу идею (обращение извне к php-файлу) не рекомендую с точки зрения безопасности.
Если бы только не ограничение в 2 запроса в секунду, и запросы не шли через сервера Битрикса, что увеличивает время ответа.. С такими ограничениями не подойдет рест, вероятно
Евгений Жуков написал: а какие процессы в crm могут быть у неавторизованных пользователей?
Нам нужно создавать сделки по запросу из приложения Внешнее приложение обращается к файлу .php, передавая нужные данные методом post, оттуда через new CCrmDeal создается новая сделка в ситсеме (Кроме этого есть масса других запросов, для получения данных или изменения сущностей) Получается, что скрипт запускается со стороны, как будто неавторизованным пользователем Скорее, тут должны быть какие-то настройки прав доступа к модулям или настройка прав для вызова методов Но где это можно настроить пока не нашли
Андрей Гомзин написал: Получается, данные методы не запускаются от имени неавторизованных пользователей
Запускаются. Просто внутри по умолчанию стоит проверка прав. Видимо, не заданы права для группы 2 на сущности (не уверен, что для Crm вообще это возможно)
Да, уже пытались настроить права, 2 группы в настройках многих модулей и CRM нет
Можно прописать авторизацию за пользователя с нужными правами через $USER ->Authorize( ); но выглядит очень ненадежно, любой сможет зайти на портал, имея ссылку на файл
В мыслях через систему токенов работать с приложением (которое будет посылать post-запросы), проверяя сначала действительность токена в запросе, а потом авторизуясь
Возможно, элементарный вопрос, но раньше никогда подобным не занимались
Битрикс24 - коробочная версия В структуре создаем файл .php, внутри требуется реализовать логику обработки входящих post-запросов, во взаимодействии с порталом
Для начала пытаемся при любом запуске файла выполнить какое-то действие и вернуть результат К примеру, вызываем в файле метод CIBlockElement::GetList - для получения списка элементов инфоблока по заданному фильтру При этом вне зависимости от того, кто обратился к файлу, выводится результат работы метода То есть, переходим в браузере по адресу https:// (адрес портала)/test.php и видим результат выполнения (например, список id по фильтру)
Однако это единственный метод (из тех, что мы нашли), который при этом отрабатывает CIBlockSection::GetList - фильтр по разделам инфоблоков не выполняется, также не создается новая сделка через $entity = new CCrmDeal; $fields = array(); return $entity->add($fields); и т.д.
При этом если запустить данный файл, авторизовавшись на портале - все отрабатывает корректно Получается, данные методы не запускаются от имени неавторизованных пользователей
Подскажите, как можно отключить данную проверку, чтобы запускать скрипт без входа на портал?