Для переноса настроек колонок создайте привязку данных на вкладке Данные в разделе Конфигурация. При создании привязки нужно настроить фильтрацию записей таблицы SysProfileData. Нажатием на кнопку Показать данные вы сможете увидеть какие именно данные будут привязаны. Обязательным условием фильтрации является условие по полю Ключ.
при вызове карточки через openCardInChain не удается передать значения для справочных полей. Значения простых типов: строки, числа, булева - переносятся
справочные - нет
this.openCardInChain({
id:"Id",
schemaName:"Tender1Page",
operation:"add",
moduleId:this.sandbox.id+"_AddTenderSuccessAction", //Автоматически устанавливаем значения в открываемой карточке
defaultValues:[ //Справочное поле полученное из модели - не переносится {name:"KmProjects", value:this.get("Project")}, //Компонуемый объект для заполнения справочного поля - не переносится {name:"Request", value:{
value:this.get("Id"),
id:this.get("Id"),
displayValue:this.get("RequestNumber") }}, //Число - переносится корректно {name:"CostPriceFromONIC", value:this.get("CostPriceFromOnicExcludingVat")}, //Устанавливаем значение поля "Стоимость" из запроса в поле //Строка - переносится нормально {name:"AmountKPwithoutVAT", value:this.get("Cost")} ] });
попробовал передавать ай-дишники... тоже не выходит
...
defaultValues:[//Справочное поле полученное из модели - не переносится{name:"KmProjects", value:this.get("Project").value},
//Компонуемый объект для заполнения справочного поля - не переносится{name:"Request", value:this.get("Id"),
//Число - переносится корректно{name:"CostPriceFromONIC", value:this.get("CostPriceFromOnicExcludingVat")},
//Устанавливаем значение поля "Стоимость" из запроса в поле //Строка - переносится нормально{name:"AmountKPwithoutVAT", value:this.get("Cost")}]
...
Добрый день, у нас в црм есть раздел “сделки”, куда попадают анкеты с формы на сайте, также вся эта форма преобразовывается в pdf и с помощью odata прикрепляется к той же сделке в црм в "файлы и примечания". Подскажите, пожалуйста, можно ли как-то реализовать, чтобы в случае изменения полей сделки менеджером в црм полностью пересоздавался/изменялся фал pdf с новыми параметрами или же можно как-то из бизнес-процессов вызвать php скрипт для создания pdf, передавая необходимый id?
В bpm'online можно реализовать процесс, который будет запускаться по изменению записи. Однако логику изменения/создания *.pdf файла необходимо будет реализовать на C#.
Вы можете реализовать веб-сервис, который генерирует этот отчет, а с помощью ODATA обратно прикрепляете его к сделке. А в бизнес-процессе вызвать этот веб-сервис.
спасибо за ответ :smile:, а реально ли сделать, чтобы все файлы из детали автоматически упаковывались в zip архив и при добавлении новых архив обновлялся, чтобы пользователь мог скачать по нажатию кнопки архив со всеми pdf?
В системе напрямую такой возможности нет, можно попробовать переопределить эту логику и добавить модулю архиватора на Javascript или С#, например https://habrahabr.ru/post/133129/
Коллеги, подскажите, пожалуйста, как можно перенести настройки отчётов раздела через svn? Подозреваю, что это некие данные, которые надо привязать к пакету. Но какие?
Подскажите как корректно загрузить пользовательский модуль с параметрами для конструктора объекта модуля. Или иным образом передать в контекст загружаемого модуля данные ?
Пример модуля
Для передачи параметров в загружаемы модуль, необходимо воспользоваться свойством instanceConfig. Скорей всего проблема связана с тем, что в конструктор модуля можно передавать только литералы объектов. this же является уже созданным экземпляром класса.
В вашем варианте это модуль элемента граф.интерфейса, со вьюхой и т.д.
наследник "Terrasoft.BaseSchemaModule"
В моем же случае нет вьюх, у Вас не описан метод init, работа в котором требуется мне.
Да и в любом случае - я воспроизвел свой юзкейс наследуясь от Terrasoft.BaseSchemaModule
В init модуля все равно нет ничего ни через instanceConfig ни через parameters
loadModule должен по определению эти объекты транслировать в конструктор.
Но по какой-то причине этого не происходит в моем кейсе...
И вопрос здесь - почему ?
На вопрос "как?" примеров и в исходниках много... но не ясно почему там работает а в моем модуле, содранном структурно под копирку - не работает.
Скорей всего это архитектурное решение, ведь даже инстанс sandbox в загружаемом модуле инциализируется отдельно. Также можно кешировать scope в свойствах глобального объекта браузера.
Так же в самом модуле, добавлена подписка на событие:
в схеме некоей карточки я добавляю модуль в зависимости, объявляю его экземпляр,
но когда дело доходит
Код внутри модуля исполняется успешно, во всех случаях кроме непосредственной подписки на события
В конечном итоге имеем ошибку "Cannot read property 'messages' of null "
внутри bootstrap.js
... getEventDescriptor:function(eventName){ var moduleDynamicMessages =this.getCurrentModuleDynamicMessages(); if(moduleDynamicMessages[eventName]){ return moduleDynamicMessages[eventName]; } var moduleDescriptor = core.getModuleDescriptor(this.moduleName); return(moduleDescriptor.messages)? moduleDescriptor.messages[eventName]||null:null; },
...
this.moduleName - оказывается в состоянии undefined
Если кто-то понимает причины, где я допустил просчет, пожалуйста подскажите.
Хотелось бы наконец разобраться как использовать функционал "своих модулей" и применять их в разработке собственной логики.
Делал модальное окно с общением между ним и карточкой из которой оно открывается через песочницу. Возможно будет полезно, вот здесь код и описание: http://www.community.terrasoft.ru/forum/topic/17970#comment-63544
Т.к. модальное окно по сути тоже модуль и песочница там работала.
"Андросов Дмитрий" написал:Ext.create(sandbox) - это что?
Эксперимент после которого, собственно подписка уже двинулась дальше, изначального фейла в котором this.sandbox = undefined
Подглядел где-то в исходниках.
...
Переработал модуль, переосмыслив, почитав статью.
да, а вот создавать экземпляр вашего модуля на LeadPage не надо
На правах, связанного вопроса...
Если я не могу/не надо создавать, как же я смогу передать контекст, при Ext.create(
я планировал передавать его - перегружая динамическое свойство, в объекте (2-ой аргумент конструктора)
Я так понимаю во время загрузки модуля, такой возможности уже не предоставляется
Или есть ?
PS: В двух словах, если можно, а в каких юзкейсах потребуется явное объявление экземпляра через Ext.create(?
"Terrasoft.CardModuleResponseInterceptor" использовать невозможно.
Вызов кода модуля, и его метода init происходит через его имя "модуля" а не класса, Вы второпях ошиблись.
т.е.
Но по неизвестной причине - мне не удается получить значения в контексте init метода.
При этом инициируя через Ext.create и явный вызов init метода у экземпляра
как раз аргументы конструктора передаются корректно, но зато не функционирует sandbox
С этого собственно все и началось.
Проблема стоит следующая: создать иерархическую(или скорее графоподобную) сущность, каждый элемент которой мог бы иметь как несколько детей, так и несколько предков и потому стандартная реализация через колонку ParentId не подходит. Вопрос следующий: как правильно(если вообще возможно) создать такую структуру данных, чтобы потом можно было выбрать всех предков скажем так:
Select accountSelect = GetAccountSelectQuery(accountId, additionalColumnNames);
var hierarhicalOptions = new HierarchicalSelectOptions {
PrimaryColumnName = "AccountId",
ParentColumnName = "ParentAccountId",
SelectType = HierarchicalSelectType.Parents,
MaxDepthParameter = select.Parameters.GetByName("MaxDepth"),
IncludeLevelColumn = true
};
QueryCondition startingCondition = hierarhicalOptions.StartingPrimaryColumnCondition;
startingCondition.LeftExpression = new QueryColumnExpression("AccountId");
startingCondition.IsEqual(select.Parameters.GetByName("RootAccountId"));
string sqlText = UserConnection.DBEngine.GetQuerySqlText(accountSelect, hierarhicalOptions);
using (DBExecutor dbExecutor = UserConnection.EnsureDBConnection()) {
using (IDataReader reader = dbExecutor.ExecuteReader(sqlText, accountSelect.Parameters)) {
while (reader.Read()) {
ancestors.Add(reader.GetColumnValue("AccountId"););
}
Идея Ваша ясна, но реализовать вот прямо как код написан вряд ли удастся, только если писать какие-то костыли. Допустим, а) если количество предков или наследников или наследников будет строго меньше N, можно сделать N полей, но это плохо с той стороны, что большое количество полей будет просто излишним, б) сделать какое-то поле, в котором будут сконкатенированы, допустим, через запятую id`шники предков, и потом его парсить, но это нарушение реляционности, да и в принципе очень проблематично. Рекомендую все же пересмотреть иерархию и подобрать другое решение.
С "наскоку" не получается в исходниках найти ту часть кода, который отвечает за реализацию поведения (часто встречающегося в типовых конфигурациях): Когда при выборе справочного значения в типовом окне справочника, происходит добавление с открытием карточки, или из какого-то пункта меню открывается карточка создания, а по завершению ее редактирования ("Сохранить") карточка закрывается, пользователь возвращается на карточку из которой он инициировал создание, где уже заполняется вновь созданным значением связанное справочное поле.
Подскажите куда копать ?
Я предполагаю что для этого поведения существует "стройный" механизм, выраженный в использовании каких-то специальных методов и т.д.
За функционал открытия новой карточки при добавлении записи в справочное поле отвечает метод actionButtonClick из LookupPageViewModelGenerator. Также Вам стоит посмотреть в метод defaultModeActionButtonClick из того же модуля.
Основная "магия" происходит в момент публикации сообщения PushHistoryState.
А можете помочь, поточнее определить/разобрать "магию".
Каким-то образом ведь должно быть определено что в открываемой карточке, во-первых надо ее закрывать при сохранении (если открыть карточку просто через OpenCardInChain такого не происходит),
во-вторых указать в какое поле искомой карточки - устанавливать значением - вновь созданную запись.
Мне необходимо добиться аналогичного поведения, только не из окна справочника, а по пункту меню "Действия"... например для карточки объекта "У" - пункт меню "Создать X"
Должна открываться карточка "X" и после ее сохранения, необходимо вернуть пользователя "на исходную карточку "Y", где специализированное поле для связи "Связанный объект Х" (Являясь справочным полем для "X") будет заполнено значением только что созданного "X".
"килочасы" отладки, позволили определить наилучшего кандидата, это событие "CardModuleResponse"
(Прямо то что нужно в атрибуты события передаются данные по уже успешно сохраненному объекту)
При условии помещения в "PushHistoryState" текущей карточки с признаком "isInChain: true"
И дальнейшим открытием карточки нового объекта через openCardInChain, "Сохранить" или "Отмена" в открываемой карточке, естественным образом вернут пользователя на страницу помещенную в PushHistoryState. При сохранении карточки обязательно произойдет публикация CardModuleResponse в который будет переданы данные о созданной записи
Казалось бы - проблем нет, подписываемся на событие и счастливы...
но нет....
На событие "CardModuleResponse" подписаться в карточке нельзя, так как в ее контексте на уровне BasePageV2 это событие уже объявлено в направлении "PUBLISH"
Как же можно обойти такое ограничение и все таки подписаться на это событие ?
(В случае с выбором из справочника, подписка происходит в рамках схемы LookupPageViewModelGenerator).
Может быть можно как-то выкрутиться через модуль, в который передавать контекст карточки, а в нем произвести подписку, т.к. там не будет зависимости от BasePageV2 ?
Здравствуйте,
Рекомендую вам написать БП в котором открывать карточку создания нужной вам сущности, после чего, из скрипт-таска послать веб сокет сообщение с id созданной записи в карточку, из которой через действия вы запустите данный процесс: http://www.community.terrasoft.ru/forum/topic/11784#comment-56699
В карточке услышав данное веб-сокет сообщение вы просто нужное поле, заполните значением по id полученным из процесса.
Информация о том, как запустить из JS процесс есть на академии.
Ну есть же механизм который используется в LookupPageViewModelGenerator
событие CardModuleResponse которое встроено в штатное платформенное поведение.
Неужели его никак нельзя использовать в собственных сценариях ?
"Севостьянов Илья Сергеевич" написал:Неужели его никак нельзя использовать в собственных сценариях ?
если вы хотите его использовать на наследниках BaseEntityPage, то не выйдет - нельзя на одного и то же сообщение подписаться в обе стороны. Вам придется реализовывать собственную пару для передачи сообщения между карточкой и карточкой. В случае со справочником [если я ничего не путаю] - LookupPage служит передатчиком между одной карточкой и другой
"Андросов Дмитрий" написал:В случае со справочником [если я ничего не путаю] - LookupPage служит передатчиком между одной карточкой и другой
Да и вот идея у меня была, забацать модуль посредник. В другой теме уже по нему выспрашиваю, пока что не очень получается :(
Мне кажется это более архитектурно-верный способ, нежели "обмазываться" событиями каждый раз.
Вам стоит смотреть в сторону использования метода openCardInChain для открытия карточки, а также для передачи в открываемую карточку имени атрибута, в который в итоге необходимо записать значение сохраняемой записи.
Передать значение можно через свойство defaultValues. Свойство defaultValues должно содержать массив объектов вида {name: "", value: ""}. В открывшейся карточке переданные значения можно считать с атрибута DefaultValues.
Возвращать Id сохраняемой записи уже через sandbox заместив BasePageV2.
Есть ли возможность интегрировать систему со сканером (обычный сканер документов) ? Чтобы в системе можно было его "определять" и все документы, отсканированные на этом сканере, можно было загружать автоматически в систему, без сохранения на компьютер ( не знаю, возможно ли это совсем без сохранения, суть в том, если через сохранение, то сохранять на комп и забирать с компа в систему нужно как-то автоматически)
В базовом функционале нет возможности настроить интеграцию со сканером. Данный вопрос вы можете решить либо собственной доработкой, либо в рамках проекта.
Она имеет в виду, что можно заказать проект у Terrasoft или у кого-то из их партнёров, чтобы они разработали интеграцию хоть со сканером, хоть с принтером, хоть со шредером.