Генератор документов - феррари на которой можно ездить только вокруг дома, Новый модуль получился хорошим но не предназначен для использования разработчиками.
Администратор
Сообщений: Баллов: 55Регистрация: 22.01.2014
15.05.2019 16:17:59
Цитата
Олег Брага написал: А getValues() провайдера Product вернет корректный массив для его пересоздания?
такого метода нет.
Цитата
Олег Брага написал: Можете дать пример кода для создания нового объекта \Bitrix\DocumentGenerator\DataProvider и инициализации его данными из уже имеющегося такого же объекта?
Тут сложно. В общем случае, оптимальный вариант - это вызвать \Bitrix\DocumentGenerator\DataProviderManager::createDataProvider() с нужными параметрами, и передать в первом аргументе ['OPTIONS']['VALUES'] массив переписываемых значений. При этом нормальные провайдеры в качестве второго аргумента принимают какое-то скалярное значение, для которого сами загружают нужные данные. И в этом случае можно переопределить скалярные (не массивы) поля этого провайдера.
С массивами и списками сложнее.
Провайдер \Bitrix\Crm\Integration\DocumentGenerator\DataProvider\Product - это наследник \Bitrix\DocumentGenerator\DataProvider\HashDataProvider. А \Bitrix\DocumentGenerator\DataProvider\HashDataProvider - это ассоциативный массив. Для \Bitrix\DocumentGenerator\DataProvider\HashDataProvider и его наследников можно сделать следующим образом: 1. Вызываем \Bitrix\DocumentGenerator\DataProviderManager::getArray() на вашем провайдере 2. Меняем значения 3. Создаем новый объект с помощью метода \Bitrix\DocumentGenerator\DataProviderManager::createDataProvider(), где второй аргумент - измененный массив с нужными данными.
Ещё можно попробовать вариант с передачей измененных значений не прямо в массив во втором аргументе, а передать в ['OPTIONS']['VALUES'] описания.
Генератор документов - феррари на которой можно ездить только вокруг дома, Новый модуль получился хорошим но не предназначен для использования разработчиками.
Администратор
Сообщений: Баллов: 55Регистрация: 22.01.2014
15.05.2019 14:46:32
Цитата
Олег Брага написал: А можете еще показать, как можно отредактировать какие-нибудь поля например NAME внутри списка продуктов в провайдере Product?
Отредактировать только если с помощью рефлексии. Залазите в \Bitrix\DocumentGenerator\DataProvider::$data нужного объекта и меняете. Должно работать. Это самый простой, но не очень чистый способ. Хотя вряд ли структура $data в будущем будет как-то меняться.
Если без рефлексии, то только пересозданием объекта \Bitrix\Crm\Integration\DocumentGenerator\DataProvider\Product и потом полной заменой списка, как в предыдущем примере.
Запрос понятен и вполне оправдан. Когда буду делать возможность редактирования значения в массивах через форму - тогда же и сделаю нормальное апи для этого дела.
Генератор документов - феррари на которой можно ездить только вокруг дома, Новый модуль получился хорошим но не предназначен для использования разработчиками.
Администратор
Сообщений: Баллов: 55Регистрация: 22.01.2014
14.05.2019 15:57:34
Цитата
Олег Брага написал: Приветствую. Подскажите пожалуйста, можно ли в событии onBeforeProcessDocument как-то добраться до списка Products полей? И модифицировать его, а то насколько я вижу методы getFields и setValues работают только с обычными не списковыми (не ArrayDataProvider) полями?
Ну или возможны какие-то другие способы, как выводить в документ не все позиции из сделки? Самый простой пример из жизни: в сделке Есть товар и услуга (доставка например), нужно сгенерить документы закрывающие, на товар нужно генерить накладную, куда доставка попасть не должна. Каким образом лучше это сделать? Насколько японимаю никаких условных операторов в шаблонах нет пока, думал получится через событие, но там смог модифицировать только обычные поля, а до списков пока не понял как добраться.
Здравствуйте. Интересный вопрос, но, я думаю, есть потребность в решении данной задачи.
Вот я набросал код, который вырезает из документа товары по признаку. Код рабочий. Перепишите функцию isSkipProduct и всё должно работать.
Небольшие пояснения, как это работает. Получаем значение из по ключу 'PRODUCTS' из провайдера документа (в данном примере это сделка). Если значение - это список товаров, то проходимся по нему, фильтруем лишнее, получаем новый массив товаров.
Дальше мы создаем новый объект ArrayDataProvider, полностью аналогичный существующему (на основе описания поля), но с другим массивом товаров. Переопределяем значение в документе по ключу PRODUCTS И обязательно переопределяем описание поля для этого ключа. Без этого не будет работать.
Будут вопросы - пишите.
Подключение js расширений ядра (sidepanel, popup...) после загрузки страницы, Как?
Администратор
Сообщений: Баллов: 55Регистрация: 22.01.2014
29.04.2019 16:09:19
Цитата
Евгений Акимов написал: Я думаю, что BX.loadExt просто не умеет подключать расширения, если в папке с расширением нет файла config.php... ?
всё верно, сейчас BX.loadExt умеет подгружать только js-расширения нового формата.
Вы можете сделать своё js-расширение, у которого укажите пути к скриптам Sidepanel, и загружать своё расширение через loadExt. Или напишите свой загрузчик, который будет загружать нужные скрипты динамически.
loadById() возвращает готовый объект \Bitrix\DocumentGenerator\Document или false. Там дальше не надо вызывать fetchObject()
Свойства документа crm
Администратор
Сообщений: Баллов: 55Регистрация: 22.01.2014
23.04.2019 16:46:31
Здравствуйте.
Поднимите объект \Bitrix\DocumentGenerator\Document с помощью метода \Bitrix\DocumentGenerator\Document::loadById()
После этого на объекте дерните getTitle(), getNumber()
Генератор документов - феррари на которой можно ездить только вокруг дома, Новый модуль получился хорошим но не предназначен для использования разработчиками.
Администратор
Сообщений: Баллов: 55Регистрация: 22.01.2014
12.04.2019 09:52:04
Mikhail Kryachek, у вас довольно продвинутый уровень использования парсера. Не проще было использовать какой-нибудь PHPWord для этих целей? Раз уж у вас полностью свой workflow работы с данными для него. Если потом надо использовать документы / конвертацию, то есть метод \Bitrix\DocumentGenerator\Document::upload(), ну либо пользоваться модулем transformer напрямую для конвертации. Всё-таки \Bitrix\DocumentGenerator\Body больше разрабатывался для работы в связке с шаблонами и провайдерами, для экосистемы битрикс24.
По поводу колбеков - идея хорошая, но не для битрикс24. Я думаю понятно, почему. Уберу final и сможете реализовать самостоятельно.
Есть идея и желание встроить в шаблоны вычисления из бизнес-процессов (с таким же синтаксисом), но руки не дошли пока.
Генератор документов - феррари на которой можно ездить только вокруг дома, Новый модуль получился хорошим но не предназначен для использования разработчиками.
Администратор
Сообщений: Баллов: 55Регистрация: 22.01.2014
11.04.2019 18:04:52
Цитата
Mikhail Kryachek написал: возможно это случилось из-за того, что вы не используете разделители в именах плейсхолдеров
Поначалу я хотел вставлять в таблицу поля в виде {PRODUCTS.NAME} - и тогда оно работало без этих промежуточных описаний. Но решили, что надо придерживаться единообразия в названиях полей, и пришлось городить такую прослойку, чтобы имена в таблицах были красивыми.
Цитата
Mikhail Kryachek написал: сейчас вот из-за такой сложной описательной части, мы хотим реализовать свой setValues метод который на вход будет принимать обычный массив и уже внутри пересобирать согласно вашим требованиям
А в чем сложность с составлением описаний? У меня была логика такая, что всё описание прячется в провайдере (который можно наследовать), составить его надо только один раз и потом оно просто работает. Если не используете провайдеры, то можно сделать обертку (какой-нибудь BodyFieldsFormatter), который будет переваривать ваш массив в нужный формат.
Генератор документов - феррари на которой можно ездить только вокруг дома, Новый модуль получился хорошим но не предназначен для использования разработчиками.
По поводу массивов. Основная сложность - это сопоставление имен полей в таблице и значений в массиве. У ArrayDataProvider есть два поля, которые берутся не из коллекции. Ну и основной момент, что внутри ArrayDataProvider лежит набор других провайдеров, а не просто набор массивов. В вашем коде, кстати, в ITEM_PROVIDER надо использовать HashDataProvider - это простой массив. Там много всего завязано на ArrayDataProvider, работать напрямую с массивами было бы сложнее из-за большого количества проверок в разных местах (чтобы понять, тот это массив или нет). Я за строгую типизацию )
По поводу примеров, постарался подробно расписать в документации по ресту
Сейчас вариантов попроще нет. Может потом придумаю какой-то способ, чтобы можно было снаружи передать структуру попроще, как-то её пометить, а внутри я уже сам сформирую объект.
Вложенных циклов сейчас нет. Можно только поиграться со вставкой множественных значений из коллекции с модификатором mseparator. Вот тут есть про него . Т.е. у вас может быть коллекция товаров. У товара множественное свойство. Можно вставить в одно место документа все значения этого свойства всех товаров без таблицы. {ProductsProductList~mseparator=2,all=y,mseparator=1} - это выведет на каждый товар новую строку, в каждой строке - все значения свойства через запятую.
Была ещё мысль сделать генерацию таблиц с произвольным набором данных (неизвестное количество столбцов). Но результат получился не очень, не стал делать. Оно ещё осталось в комментариях у класса \Bitrix\DocumentGenerator\Body\DocxXml в самом конце.
Цитата
Mikhail Kryachek написал: Прямо очень не хватает своих меток как единичных, так и блочных
О каких метках речь? Опишите подробнее, подумаю, что можно сделать.
final позволяет мне не задумываться над обратной совместимостью. Это позволяет мне рефакторить код по своему усмотрению. Для разработчиков - да, неудобно. Но если бы после обновления сломалась реализация из-за того, что я изменил сигнатуру, тоже было бы не очень.
Как только дойдут руки, я планирую убрать final с наследников Body, дать возможность задавать свой тип Body в шаблонах. Станет легче - наследуйтесь сколько хотите, парсите файлы самостоятельно. По срокам ничего не скажу. Надеюсь, в этом году.
Цитата
Mikhail Kryachek написал: Как обстоят дела с конвертацией файлов, например docx->pdf НЕ на серверах Битрикса
Планируется, что модуль конвертации файлов transformercontroller уйдёт в коробку в составе виртуальной машины. Можно будет с помощью неё развернуть у себя инфраструктуру и конвертировать. По срокам тоже ничего не скажу, может быть в этом месяце.
Генератор документов - феррари на которой можно ездить только вокруг дома, Новый модуль получился хорошим но не предназначен для использования разработчиками.
Произвольное значение сейчас передать нельзя, перед вставкой дергается \Bitrix\DocumentGenerator\Body\DocxXml::printValue() - там строка подготавливается для вставки в xml.
По поводу работы с контентом - в примере $content - это не содержимое xml-файла, это весь docx файл, который представляет собой zip-архив. Работать с ним напрямую нельзя, надо сначала его распаковать, найти внутри нужный xml и работать уже с ним. Для примеров можно посмотреть \Bitrix\DocumentGenerator\Body\ZipDocument::open() - тут архив распаковывается потом через \ZipArchive::getFromName() - можно получить доступ к xml-файлу и работать с его контентом. После работы надо сохранить содержимое через \ZipArchive::addFromString()