Добрый день!

Допустим есть контрагенты с типом А и B.

Если у контрагента тип А, то необходимо для детали Адреса у контрагента делать НЕактивным действие удалить на детали.

 

Для этого в  схеме детали

были переопределены следующие методы

 

        getDeleteRecordButtonEnabled: function() {

                var  ican=this.get("IsMyEnabled");

                return ican.value;

                },

                

                getDeleteRecordMenuItem: function() {

                    return this.getButtonMenuItem({

                        Caption: {"bindTo": "Resources.Strings.DeleteMenuCaption"},

                        Click: {"bindTo": "deleteRecords"},

                        Enabled: {bindTo: "getDeleteRecordButtonEnabled"},

                        Visible: {bindTo: "IsEnabled"}

                    });

                }

где виртуальный атрибут IsMyEnabled должен быть false, если у контрагента тип А.

Как и где надо достучаться в схеме детали адреса контрагентов до типа контрагента?

То есть как и где надо достучаться в схеме детали до какого-либо поля родительской записи?

Предположительно, что метод заполнения атрибута будет таким:

                setMyEnabled: function() {

                var accountId = this.get("MasterRecordId");

                if (!accountId) {

                    return;

                }

                var select = this.Ext.create("Terrasoft.EntitySchemaQuery", {

                        rootSchemaName: "Account"

                    });

                select.addColumn("UsrAccountStatus.Id","AccStatus");

                select.getEntity(accountId.value, function(result) {

                    if (!result.success) {

                        return;

                    }

                    if (result.entity.get("AccStatus")) {

                        if (result.entity.get("AccStatus")===UsrConsts.AccountStatus.Approve) {

                        this.set("IsMyEnabled", true);

                        }

                        else {

                        this.set("IsMyEnabled", false);    

                        }

                    }

                }, this);

                

            }

 

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

 

Нравится

7 комментариев

Дарья, тут описан пример доступности действия в зависимости от значения стадии.Возможно, для детали потребуется что-то аналогичное.

Либо пойти другим путём и реализовать невозможность удаления при помощи раздачи прав на записи детали.

Зверев Александр,

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

Можно попробовать обращаться к записи детали и добираться к полю связанной записи основного раздела по связям.

Зверев Александр,

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

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

Зверев Александр,

Добрый день) Все забываю отписаться.

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

В методе initData надо делать - для блокировки действий при инициализации детали

ниже пример

Сделали так:

 

виртуальный атрибут

        attributes: {

                "IsMyEnabled": {

                dataValueType: Terrasoft.DataValueType.BOOLEAN,

                value: false

            }

        },

 

 

                //заполнение атрибута для определения доступности действия

                setMyEnabled: function() {

                var accountId = this.get("MasterRecordId");

                if (!accountId) {

                    return;

                }

                var select = this.Ext.create("Terrasoft.EntitySchemaQuery", {

                        rootSchemaName: "Account"

                    });

                select.addColumn("UsrAccountStatus.Id","AccStatus");

                select.getEntity(accountId, function(result) {

                    if (!result.success) {

                        return;

                    }

                    if (result.entity.get("AccStatus")) {

                        if (result.entity.get("AccStatus")===UsrConsts.AccountStatus.Approve) {

                        this.set("IsMyEnabled", false);

                        }

                        else {

                        this.set("IsMyEnabled", true);

                        }

                    }

                    }, this);

            },

 

 

.//при обновлении детали вызвали метод свой

    //при обновлении детали

// у нас статус контрагента(от которого зависит доступность) меняется с помощью специального действия, после которого вызывается updateDetail

                updateDetail: function(config) {

                    this.callParent(arguments);

                    //вызов заполнения атрибута для определения доступности действия

                        this.setMyEnabled();

                    if (config.reloadAll) {

                        var detailInfo = this.getDetailInfo();

                        this.set("MasterRecordId", detailInfo.masterRecordId);

                        this.set("DetailColumnName", detailInfo.detailColumnName);

                        this.set("Filter", detailInfo.filter);

                        this.set("CardPageName", detailInfo.cardPageName);

                        this.set("SchemaName", detailInfo.schemaName);

                        this.set("DefaultValues", detailInfo.defaultValues);

                        this.set("UseRelationship", detailInfo.useRelationship);

                        this.set("RelationType", detailInfo.relationType);

                        this.set("RelationTypePath", detailInfo.relationTypePath);

                        this.set("RelationshipPath", detailInfo.relationshipPath);

                        this.set("IsGridDataLoaded", false);

                        this.set("IsClearGridData", true);

                        this.set("ActiveRow", null);

                        this.set("SelectedRows", []);

                        this.set("IsEnabled", detailInfo.isEnabled);

                        this.set("ProfileKey", detailInfo.profileKey);

                        this.initRelationshipButton(this.loadGridData);

                    } else {

                        var primaryColumnValue = config.primaryColumnValue;

                        this.loadGridDataRecord(primaryColumnValue);

                        this.fireDetailChanged({

                            action: "edit",

                            rows: [primaryColumnValue]

                        });

                    }

                },

 

//при инициализации детали вызвали метод свой

    //при инициализации детали

                initData: function(callback, scope) {

                    //вызов заполнения атрибута для определения доступности действия

                    this.setMyEnabled();

                    this.callParent([function() {

                        Terrasoft.chain(

                            this.initGridRowViewModel,

                            function(next){

                                this.initGridData();

                                this.initSortActionItems();

                                this.reloadGridColumnsConfig();

                                this.initRelationshipButton(next);

                            },

                            function(next){

                                this.loadGridData();

                                this.initToolsButtonMenu();

                                this.mixins.GridUtilities.init.call(this);

                                this.initDetailRunProcessButtonMenu(next);

                            },

                            function() {

                                callback.call(scope);

                            },

                            this);

                    }, this]);

                },

                

 

                //переопределение доступности удалить - часть 1

                getDeleteRecordButtonEnabled: function() {

                    var  ican=this.get("IsMyEnabled");

                    var ican2 = this.isAnySelected();

                    return ican2 && ican;

                },             

                

                

                //переопределение доступности удалить - часть 2

                getDeleteRecordMenuItem: function() {

                    return this.getButtonMenuItem({

                        Caption: {"bindTo": "Resources.Strings.DeleteMenuCaption"},

                        Click: {"bindTo": "deleteRecords"},

                        Enabled: {bindTo: "getDeleteRecordButtonEnabled"},

                        Visible: {bindTo: "IsEnabled"}

                    });

                },

 

                isAnySelected: function() {

                    var selectedItems = this.getSelectedItems();

                    return selectedItems && (selectedItems.length > 0);

                },

Спасибо за уточнение!

Показать все комментарии

Здравствуйте! Подскажите пожалуйста, есть ли возможность сделать в bpm используя класс Insert, запрос такого вида:

Insert into "имя сторонней базы"."имя таблицы этой базы" (...) values (...);

т.е. сделать инсерт в другую стороннюю базу, или прочитать от туда таблицу. Если да, то как сделать.

Нравится

3 комментария

Скорее всего нет. Особенно, если система в облаке)

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

Можно создать view с запросом на выборку, триггерами вместо вставки, изменения и удаления в стороннюю базу. Затем создать привязанную к ней схему с такими же колонками и проставленным признаком «представление» и работать с ней так же, как с обычной.

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

Показать все комментарии

Товарищи помогите.

БЦ  дергает код на сервере, этот код забирает данные из другой системы и обновляет запись контрагента путем прямого SQL запроса.

Все работает  но проблема с обновление пользовательского интерфеса.(Ну тобишь пользователь должен в интерактиве увидеть результат). Сейчас  я в клиенском коде кручу в потоке jQuery таймер и тыкаюсь в БД проверяя наличие изменений и вывожу диалоговое окошко. Но данный подход, мне уж больно не нравится.

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

 

Нравится

2 комментария
Лучший ответ

Чисто в теории:

- код на сервере помимо sql-вставок, генерирует сигнал по web-socket, что изменена запись

-на клиенте развернуть listener, будет принимать сигнал, выдавать пользователям сообщение

Чисто в теории:

- код на сервере помимо sql-вставок, генерирует сигнал по web-socket, что изменена запись

-на клиенте развернуть listener, будет принимать сигнал, выдавать пользователям сообщение

Показать все комментарии

Коллеги, добрый день!

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

1. Создается объект UsrVwTest , который наследуется от базового, в нем не добавляется ни одного поля (в view будет 1 колонка с идентификаторами контакта), у него устанавливается признак, что это представление в базе, он сохраняется и публикуется.

2. После этого, через расширение SqlExecutor выполняется что-то в духе

create view UsrVwTest as select top 1 Id as 'Id' from Contact

3. После это прямо из консоли пробую посчитать записи, которые там есть, выполняя следующее:

var esq = this.Ext.create("Terrasoft.EntitySchemaQuery", { rootSchemaName: "UsrVwTest" });
esq.addColumn("Id");
esq.getEntityCollection(function (result) {
	if (!result.success) {
		// обработка/логирование ошибки, например
		this.showInformationDialog("Ошибка запроса данных");
		return;
	}
	console.info(result.collection.getCount());
}, this);

Консоль выдает мне 1, то есть проблем с доступом к view нет, там одна строка, как и должно быть.

После этого я повторяю тот же алгоритм на on-site проекте 7.11, в том же порядке. После этого я на аналогичное обращение к view из консоли получаю 500 (InvalidObjectStateException). Запрос в Network падает также с кодом "ErrorCode":"InvalidObjectStateException". Обработка результата падает в ветку с !result.success. Пробовал дополнительно компилировать конфигурацию на разных этапах алгоритма, создавать view различными способами (напрямую в базе, через установку скрипта в конфигурации и т.д.), получаю тот же ответ. Названия view в базе и в конфигурации совпадают, название и количество колонок тоже.  Кроме того, на проекте уже есть view, реализованные ранее, с которыми ведется работа, они реагируют по-разному. Некоторые так же выдают 500, некоторые послушно пишут количество записей внутри себя. 

Резюмируя, мог бы кто-то подсказать, в чем может быть проблема или какой единственно верный алгоритм реализации такой связки? Поиск по статьям привел меня именно к тому алгоритму, который заработал на демо-стенде, но упорно не хочет работать на on-site площадке. 

Нравится

2 комментария

Поправка:

По всей видимости, все уже существующие представления ошибок не вызывают. Случаи, когда запрос к ним из консоли выдает 500 - превышение 20 000 записей на выгрузку. 

 

Все получилось. Оказалось, что view нужно создавать именно как dbo.ViewName, а не просто ViewName, иначе InvalidObjectName

 

Показать все комментарии

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

Нравится

3 комментария

Выдачу прав в зависимости от типа можно сделать при помощи БП, срабатывающего при вставке. А невозможность добавить нужного типа — или кодом дорабатывать, или включить в объекте справочника администрирование по записям и выдать права.

Спасибо, можете, подробнее пояснить как задать права на определенный тип объекта, в Управлении Конфигурацией увидел права ко всему объекту, 

А задать права на конкретные записи можно попробовать через базу.

Показать все комментарии

Здравствуйте. Есть рaздел в нем есть несколько карточек(страниц)редактирования(каждая из которых отрабатывает зависимости от значения поля - справочника ). В верху всех карточек присутствует выпадающее меню Отчеты, куда попадают печатные формы которые закреплены за этим разделом и для все карточек они(печатные формы) такие же. Можно ли настроить отображения этих отчетов(их кнопок) в зависимости от текущей страницы редактирования? 

bpm 7.11

Нравится

1 комментарий

Андрей, здравствуйте!

На данный момент нет похоже функционала, который фильтровал либо накладывал условия при работе с печатными формами (в том числе и кнопка "Печать").

Похожий запрос рассматривался в соседнем топике - https://community.terrasoft.ru/questions/filtr-pecatnyh-form

Показать все комментарии

Всем привет. Присутствует отчет(печатная форма) который по логике отображается в карточке раздела. Всего есть несколько карточек(страниц). Есть ли возможность скрыть контрол отчета в зависимости от открытой страницы в разделе.

Нравится

1 комментарий

Андрей, здравствуйте!

На данный момент нет похоже функционала, который фильтровал либо накладывал условия при работе с печатными формами (в том числе и кнопка "Печать").

Похожий запрос рассматривался в соседнем топике - https://community.terrasoft.ru/questions/filtr-pecatnyh-form

Кнопка "Печать" формируется если есть записи в коллекции. 

Показать все комментарии

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

Нравится

1 комментарий

Получить содержимое раздела обращений можно так:

select * from [case]

Если нужно текстовые значения справочных полей, то пишутся join-ы с таблицами справочников.

Для деталей аналогично, только дописать where с фильтрацией детали по Id записи основного раздела.

Теги — это обычная деталь-развязка со значениями справочника. В таблице CaseTag будет справочник тегов обращения, в CaseInTag — связь обращений и тегов.

Показать все комментарии

Коллеги, добрый день.

Заказчик хочет через мастер раздела создавать новые вкладки. И в зависимости от значения поля, например, "Состояние" - отображать или скрывать вкладки.

Хочу реализовать это через справочник. Можно ли название новой вкладки, созданной Пользователем через мастер раздела - автоматически размещать в справочник?

Спасибо.

Нравится

8 комментариев
Лучший ответ

На проекте мы такую логику хардкодили по страшному. Причём там затык в том, что нельзя из коллекции табов (вкладок) просто так её удалить. Надо сохранять удалённые и динамически менять. короче, та ещё задачка) Кстати пару тем по этому поводу на форуме есть.

+ Мастер названия вкладок ну никак не сохранит в справочник.

На проекте мы такую логику хардкодили по страшному. Причём там затык в том, что нельзя из коллекции табов (вкладок) просто так её удалить. Надо сохранять удалённые и динамически менять. короче, та ещё задачка) Кстати пару тем по этому поводу на форуме есть.

+ Мастер названия вкладок ну никак не сохранит в справочник.

Данила, спасибо. Вроде как Заказчик не ставил задачу по удалению вкладок. Достаточно скрыть :)) Мониторила форум. Нашла всего одну тему и ту от какого-то махрового года(2014).

Может пойти от обратного. Изменить в мастере раздела карточку с названием новой вкладки. Заменить там текстовое поле на справочник? Это возможно?

Вот тема. Ну вот нельзя просто у вкладки visible проставить)

ну всё же. Можно или нет создание через мастер раздела новой вкладки, эту вкладку  как-то к справочнику привязать?

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

Александр, "...можно найти то место..." Не подскажите, где искать?

Предполагаю, что какой-то из схем со словами SectionDesigner или SectionWizard в названии. Сходу не нашёл.

Коллеги, всем спасибо

Показать все комментарии

Здравствуйте! Может кто-нибудь подскажет как решать проблему, с отображением данных уведомлений.

Изображение удалено.

Сами уведомления приходят, всё хорошо, но они не отображаются "красными кружками", в боковой панели, на "Центр уведомлений". Версия 7.11

Изображение удалено.

Нравится

3 комментария

Механизм уведомлений будет работать корректно при правильно настроенных сокетах. С порядком настройки сокетов можно ознакомиться здесь. Также следует обратить внимание на тот факт, что обязательно должен быть активирован компонент "WebSocket Protocol". Ниже прикреплен скриншот для наглядности:

Мотков Илья,

Cпасибо за ответ, сделал как написано, в консоли отобразилась надпись 

WebSocket-connection opened for url:ws://demo.bpmonline.com/0/Nui/ViewModule.aspx.ashx

а так же типа такого периодически сыпется

Уведомления всё равно не появляются, т.е. сами уведомления приходят, но оповещений на уведомления так и не появляются.

Эти уведомления ведь могут работать и на пользовательские разделы?

Насколько понимаю Ваш сайт размещен локально. В данном случае Вам следует обратить внимание на следующие факторы:

1. Должна использоваться только регламентированная Terrasoft операционная система (только Windows в качестве сервера для разворачивания и для клиентской ПК. Также для клентского ПК еще может использоваться MAC OS но только в браузере Safari);

2. Должен использоваться только регламентированный Terrasoft браузер (Chrome, Mozilla последней актуальной версии, Safari под MAC OS);

3. Должны быть открыты и корректно настроены веб-сокеты, ссылка выше.

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

Показать все комментарии