Добрый день. Подскажите пожалуйста, не как не могу решить данный кейс (причем когда-то такой решал давно но не могу не как вспомнить как).

Есть кнопка в группе кнопок "Действие" - "Отправить на визирование", она запускает процесс визирования. Данная кнопка должна быть активна если в таблице визирования уже есть как минимум одна положительная запись (автор согласовал). Для этого сделал запрос к базе данных и получил результат. Через свойство "Enabled" нужно реализовать доступность кнопки.

Код кнопки:

actionMenuItems.addItem(this.getButtonMenuItem({
	"Caption": VisaHelper.resources.localizableStrings.SendToVisaCaption,
	"Tag": VisaHelper.SendToVisaMenuItem.methodName,
	"Enabled": {"bindTo": "canEntityBeOperated"}
}));

"Enabled": {"bindTo": "canEntityBeOperated"} - сюда и надо отправить true и false.

Код запроса к базе данных:

var opportunityId = this.get("Id");
var ownerContact = "";
if (this.get("Owner")) {
	ownerContact = this.get("Owner").value;
}
var esq = this.Ext.create("Terrasoft.EntitySchemaQuery", {
	rootSchemaName: "KtOpportunityVisa"
});
esq.addColumn("VisaOwner.Contact", "VisaOwnerContact");
esq.addColumn("KtOpportunity", "KtOpportunity");
esq.addColumn("Status", "Status");
var esqOwnerContactFilter = esq.createColumnFilterWithParameter(Terrasoft.ComparisonType.EQUAL,
	"VisaOwner.Contact", ownerContact);
var esqOpportunityFilter = esq.createColumnFilterWithParameter(Terrasoft.ComparisonType.EQUAL,
	"KtOpportunity", opportunityId);
var esqVisaСanceledFilter = esq.createColumnFilterWithParameter(Terrasoft.ComparisonType.EQUAL,
	"Status", KtConfigurationConstantsKarTel.VisaStatus.Positive);
esq.filters.add("esqOwnerContactFilter", esqOwnerContactFilter);
esq.filters.add("esqOpportunityFilter", esqOpportunityFilter);
esq.filters.add("esqVisaСanceledFilter", esqVisaСanceledFilter);
esq.getEntityCollection(function (result) {
	if (result.success && result.collection.getCount() === 0) {
		return false;
	} else {
		return true;
	}
}, this);

Так как запрос асинхронный то на сколько помню решается это через Terrasoft.chain с Callback, но как это сделать хоть убейте не помню.

Нравится

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

По поводу упомянутого механизма Вы недавно задавали вопрос в этой теме. Также см. публикацию.

По поводу упомянутого механизма Вы недавно задавали вопрос в этой теме. Также см. публикацию.

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

 решил вопрос через создание в таблице процесса что срабатывал при изменении в ней и отправлял сообщение на фронт, а на фронте подписался на него и запускаю функцию что меняет атрибут который и дает ответ в каком состоянии должна быть кнопка. Могу написать код реализации тут если кому нужно. Но в итоге бизнес решил что им это не надо потому далее не оптимизировал код. Сейчас проблема в активности этой кнопки в совмещенном режиме, создал отдельный вопрос

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

Собственно, нужно получить некие данные с внешнего API, и потом нарисовать их на странице раздела. Прошу подсказки, в какую сторону смотреть и двигаться. В Академии есть пример с добавлением строки-приветствия. Однако, совсем не понятен принцип работы кода с примера. Документация по Terrasoft Javascript API так же не понятна. Прошу подсказки, куда смотреть и в какую сторону двигаться.

Нравится

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

Если сервер API предоставляет специализированные заголовки CORS то в Вашем распоряжении вся мощь JavaScript в клиентской схеме, делайте запросы (н/п используя инструментарий используемой библиотеки Ext.JS AJAX), обрабатывайте ответы - устанавливайте атрибуты для заполнения полей и т.д.

Если сервер API не предоставляет специализированные заголовки CORS то в данном случае Вам придется писать код C# (Здесь я сильно не подскажу что да как, веб-сервис что-то там такое есть)
После чего можете например по websocket протоколу пробросить события с данными в клиентские карточки (как это сделать обсуждалось вот здесь)

"Севостьянов Илья Сергеевич" написал:Если сервер API не предоставляет специализированные заголовки CORS то в данном случае Вам придется писать код C#

Из js вызываете сервис. В сервисе обычные post/get запросы с помощь System.Web. Получаете ответ от сервера, делаете return, в js-коллбеке проходит ответ в json-строке. Сериализуете, обрабатываете далее как угодно

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

Добрый день!
Задача такая - в разделе Заказы есть деталь Площадка - объект, куда необходимо доставить продукт. Площадок в заказе может быть несколько. Необходимо отобразить на карте объекты в выбранных заказах.

На странице OrderSectionV2 добавила кнопку "Показать площадку на карте", при этом в В define и function прописала "MapsUtilities", "MapsHelper".
Добавила функцию:

openShowOnMap: function() {
                                var items = this.getSelectedItems();//отмеченные галкой заказы - массив
                                var Farm = [];//массив площадок
                                var select = Ext.create("Terrasoft.EntitySchemaQuery", {
                                        rootSchemaName: "UsrPlatform1C"
                                });
                                select.addColumn("UsrPlatform");
                                select.addColumn("UsrOrder");
                                select.filters.add("UsrPlatformId", this.Terrasoft.createColumnInFilterWithParameters("UsrOrder", items));
                                select.getEntityCollection(function(result) {
                                        if (result.success) {
                                                Terrasoft.each(result.collection.getItems(), function(item) {
                                                        Farm.push(item.set("UsrPlatform").value);
                                                });
                                        }
                                });
                                var selectS = Ext.create("Terrasoft.EntitySchemaQuery", {
                                        rootSchemaName: "UsrFarm"
                                });
                                selectS.addColumn("Id");
                                selectS.addColumn("UsrName");
                                selectS.addColumn("UsrAdress");
                                selectS.addColumn("UsrCity");
                                selectS.addColumn("UsrRegion");
                                selectS.addColumn("UsrCountry");
                                selectS.addColumn("UsrGPSN");
                                selectS.addColumn("UsrGPSE");
                                selectS.filters.add("FarmId", this.Terrasoft.createColumnInFilterWithParameters("Id", Farm));
                                selectS.getEntityCollection(function(result) {
                                        if (result.success) {
                                                var mapsConfig = {
                                                        mapsData: []
                                                };
                                                result.collection.each(function(item) {
                                                                var address = [];
                                                        if (item.get("UsrCountry") && item.get("UsrCountry").displayValue) {
                                                                address.push(item.get("UsrCountry").displayValue);
                                                        }
                                                        if (item.get("UsrRegion") && item.get("UsrRegion").displayValue) {
                                                                address.push(item.get("UsrRegion").displayValue);
                                                        }
                                                        if (item.get("UsrCity") && item.get("UsrCity").displayValue) {
                                                                address.push(item.get("UsrCity").displayValue);
                                                        }
                                                        address.push(item.get("UsrAdress"));
                                                        var dataItem = {
                                                                caption: item.get("UsrName"),
                                                                content: "

"

+ item.get("UsrName") + "
"
+ address.join(", ") + "
",
                                                                address: item.get("UsrAdress") ? address.join(", ") : null,
                                                                //конвертирование полей долготы и широты
                                                                gpsN: parseFloat(item.get("UsrGPSN")),
                                                                gpsE:  parseFloat(item.get("UsrGPSE")),
                                                                updateCoordinatesConfig: {
                                                                        schemaName: "UsrFarm",
                                                                        id: item.get("Id")
                                                                }
                                                        };
                                                        mapsConfig.mapsData.push(dataItem);
                                                });
                                                MapsUtilities.open({
                                                        scope: this,
                                                        mapsConfig: mapsConfig
                                                });
                                        }
                                }, this);
                        }

При отладке кода выяснила, что фильтрация по выбранным заказам выполняется, получаем выбранные заказы и площадки в этих заказах.
А в запросе при выборе Адреса, Региона, Страны получаем данные ВСЕХ площадок, которые есть в базе данных, а не только полученных из предыдущего запроса. (скриншот во вложении). Помогите, пожалуйста, разобраться в чем ошибка в фильтрации в запросе!!!

Нравится

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

Здравствуйте, Юлия.

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

И на момент добавления фильтра в строке:

selectS.filters.add("FarmId", this.Terrasoft.createColumnInFilterWithParameters("Id", Farm));

массив Farm пустой. Следовательно, фильтрация не отрабатывает. Рекомендую Вам смотреть в сторону использования метода Terrasoft.chain или же формировать второй запрос к базе данных в callback функции первого запроса, а если точнее то сразу после кода:

Terrasoft.each(result.collection.getItems(), function(item) {
            Farm.push(item.set("UsrPlatform").value);
        });

Илья, спасибо большое за Ваш ответ.

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

Добрый день!
Подскажите пожалуйста как добавить действие в карточку контакта, так чтоб оно не сыпало при вызове из combined mode и не было доступно в разделе?
Сейчас есть замещающая страница ContactPage и переопределен метод getActions, в который добавлено действие: actionMenuItems.addItem(this.getButtonMenuItem({
"Caption": { "bindTo": "Resources.Strings.UsrSetToSaleCaption" },
"Tag": { bindTo: "setToSaleProcess" }
}));
при вызове из карточки работает нормально, но из совмещенного режима падает с ошибкой, что метод не найден.
Версия 7.7.0.2293

Нравится

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

Здравствуйте!
Посмотрите здесь - http://www.community.terrasoft.ru/forum/topic/13848

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

Нужно показывать действие по условию.
Сделал действие в карточке:

                getActions: function() {
                    var actionMenuItems = this.callParent(arguments);
                    actionMenuItems.addItem(this.getButtonMenuItem({
                        "Caption": {"bindTo": "Resources.Strings.UsrFormContractCaption"},
                        "Tag": "FormContract",
                        "Visible": {"bindTo": "FormContractVisible"}
                    }));
                    return actionMenuItems;
                },
                FormContractVisible: function(){
                    var contract = this.get("UsrContract");
                    var state = this.get("Status")?this.get("Status").value:false;
                    if(!contract && state == Constants.OrderStatus.formation){
                        return true;
                    }else{
                        return false;
                    }
                }

При режиме карточки всё отрабатывает отлично.
Далее добавил действие в Section.

            getSectionActions: function(){
                var actionMenuItems = this.callParent(arguments);
                actionMenuItems.addItem(this.getButtonMenuItem({
                    "Caption": {"bindTo": "Resources.Strings.UsrFormContractCaption"},
                    "Tag": "FormContract",
                    "Visible": {"bindTo": "FormContractVisible"}
                }));
                return actionMenuItems;
            },
            FormContractVisible: function(){
                var activeRow = this.getActiveRow();
                if(!activeRow) return;
                var Contract = UsrContract || activeRow.values.UsrContract;
                var Status = Status || activeRow.values.Status.value;
                if(!Contract && Status == Constants.OrderStatus.formation){
                    return true;
                }else{
                    return false;
                }
            }

При режиме combined тоже всё стало отрабатывать. Но если в карточке изменить поле, например UsrContract то видимость уже не изменяется. Можно после сохранения карточки, например в функции onCardModuleResponse переинициализировать действия, но как это сделать не нашёл.
Подскажите как правильно реализовать задачу.

Версия 7.7

Нравится

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

Тут есть две проблемы:

1. В activeRow попадают только те колонки, что выведены на реестр. Следовательно и проверять в своей функции FormContractVisible вы можете только те колонки что видны вам в реестре(!). Иначе значения будут неопределенными, и результат проверки явно ошибочным;

2. Метод getSectionActions срабатывает только при смене фокуса между строками реестра, то есть, что бы ваши actionMenuItems увидели изменения в комбинированном режиме, вам нужно перейти от одной записи к другой и обратно, что, не очень то и удобно.

Что бы избежать первой проблемы, вам стоит из activeRow только гуид записи, а остальное вытягивать с помощью запросов ESQ.

Что бы по изменению значения на форме, секция об этих изменениях узнавала в реальном времени, без необходимости переключатся по записям.
Вам стоит использовать сообщения. (sandbox)
Поищите по конфигурации примеры использования, их очень много, ключевые слова: sandbox.subscribe и sandbox.publish

Алгоритм конечной реализации для комбинированного может быть приблизительно таким:

1. Видимость вашего actionMenu итема в секции, вы привязываете к атрибуту секции;
2. В секции, объявляете сообщение, в методе init подписываетесь на него через sandbox.subscribe;
2a. Обработчик этого сообщения меняет атрибут, к которому привязана видимость экшена.
3. В карточке по событию изменения целевых полей, вы генерируете адресное сообщение через sandbox.publish

Все, меняется карточка, про это узнает секция, меняется атрибут, меняется видимость экшена.
Если возникнут точечные вопросы во время реализации, пишите, постараемся ответить.

Первое было решено. Я переопределил функцию которая указывает что тянуть в activeRow. Я вытягиваю в этот объект нужные мне колонки без запросов.

Сообщение уже отправляется из карточки в секцию, при сохранении карточки. И потом дёргается как-раз функция onCardModuleResponse. - это базовая логика. Только вот я привязывал видимость действия к функции, а может действительно следовало к атрибуту. Как-то я упустил этот момент. Попробую...

Да. Надо было всего-лишь в секшене видимость подвязать на атрибут.
Как-то я протупил) Спасибо за наводочку)

"Щиголь Максим" написал:Алгоритм конечной реализации для комбинированного может быть приблизительно таким:

1. Видимость вашего actionMenu итема в секции, вы привязываете к атрибуту секции;
2. В секции, объявляете сообщение, в методе init подписываетесь на него через sandbox.subscribe;
2a. Обработчик этого сообщения меняет атрибут, к которому привязана видимость экшена.
3. В карточке по событию изменения целевых полей, вы генерируете адресное сообщение через sandbox.publish

и такое workaround планируется считать нормальным решением?

"Владимир Соколов" написал:и такое workaround планируется считать нормальным решением?

На то он и workaround, хотя типовое решение не сильно и отличается от него. Т.к. в данном случае было найдено существующее сообщение sandbox. Писать своё, как я понимаю, не пришлось. Проблема была решена подвязкой видимости на атрибут, который изменяется в секции по сообщению CardModuleResponse.

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

Создал для контрагента действие:

              getActions: function() {
                  var actionMenuItems = this.callParent(arguments);
                  actionMenuItems.addItem(this.getActionsMenuItem({
                      "Caption": { "bindTo": "Resources.Strings.SxActionOpportunity" },
                      "Enabled":  { bindTo: "isClient" },
                      methodName: "runOpportunityManagement"
                  }));
                  return actionMenuItems;
              },

Действие должно быть активно только для контрагента с типом Клиент или Потенциальный клиент. Написал метод:

              isClient: function() {
                  var type = this.get("Type");
                  if(type) {
                      type = type.value;
                  }
                  if(type === Home32Constants.Account.Type.Client || type === Home32Constants.Account.Type.PotencialClient){
                      return true;
                  }else{
                      return false;
                  }
              },

Функция возвращает "true" а действие всё-равно не активно. А вот если закрыть левую панель(там где список записей раздела) и обновить страничку - всё отрабатывает как нужно.

Та же ошибка наблюдается и с Caption. Если открыта панель, то Caption пустой, а если закрыта - всё ок.
Я так понимаю если открыта эта панель система считает, что пользователь находится в разделе...

Вопрос с Caption решается добавлением Strings в Section раздела, а вот как быть с Enabled не понятно.

Нравится

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

Добрый день, Вячеслав!

Код должен отрабатывать, на первый взгляд ошибок нет.
Скорее всего ошибка в чем-то другом.
Я Вам написал личное сообщения для продолжения анализа возникшей ошибки.

В версии 7,4 удалось решить проблему таким образом:

              initCardActionHandler: function() {
                  this.callParent(arguments);
                  var propertyNames = [
                      "isClient"
                  ];
                  this.Terrasoft.each(propertyNames, function(propertyName) {
                      this.on("change:" + propertyName, function(model, value) {
                          this.sandbox.publish("CardChanged", {
                              key: propertyName,
                              value: value
                          }, [this.sandbox.id]);
                      }, this);
                  }, this);
              },

В следующем проекте уже на версии 7.5 стоит похожая задача, но данное решение уже не помогает.

В версии 7.5 такое решение тоже будет работать если isClient будет свойством, а не функцией. Для того, чтоб все работало, нужно в Карточке сделать isClient и уже к нему байндить "Enabled" действия.

Да. Действительно если биндиться на свойство всё отрабатывает. Спасибо!

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

Добрый день!
Добавила действие в раздел, при нажатии на действие должен происходить запуск процесса, но не происходит. С чем это может быть связано?

Реализация - в прикрепленном в файле

Нравится

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

Используемый метод showGrafInfo должен выглядеть следующим образом:

showGrafInfo: function() {
var processArgs = {
sysProcessName: "ProcessGrafShip",
parameters: {
}
};
ProcessModuleUtilities.executeProcess (processArgs);
},

Спасибо, получилось

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

Здравствуйте!
Помогите, пожалуйста, добавить кнопку в список "Действие" в карточке контрагента

Нравится

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

Здравствуйте, Эмин!
Это типичная задача. следующим кодом в замещающем клиентском модуле:

structure.userCode = function() {
...
	this.actions.push({
		caption: resources.localizableStrings.ActionCaption,
		methodName: 'actionMethod'
	});
	this.methods.actionMethod = function() {
		alert('test');
	};
...
};

"Андрей Каспаревич" написал:

Здравствуйте, Эмин!

Это типичная задача. следующим кодом в замещающем клиентском модуле:

structure.userCode = function() {

...

        this.actions.push({

                caption: resources.localizableStrings.ActionCaption,

                methodName: 'actionMethod'

        });

        this.methods.actionMethod = function() {

                alert('test');

        };

...

};

С уважением,

Каспаревич Андрей

Эксперт 3-й линии поддержки


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

Uncaught TypeError: Cannot read property 'push' of undefined 

Разобрался. Для карточки контрагента необходимо сначала создать переменную-массив, а затем приравнять ее к this.actions

var myActions = [];
myActions.push({
 caption: resources.localizableStrings.Name,
 methodName: 'Method'
});
this.actions = myActions;

Еще раз спасибо за помощь!

Эмин, рад, что Вы разобрались! Я как раз забыл это упомянуть.

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

подскажите пожалуйста, как создать на нужной детали, новое "Действие"?

Нравится

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

В нужном вам гриде детали во вкладке не визуальные, создайте новый Action, в конфигурации можете глянуть примеры, начинаются вкладки действий в не визуальных со слова "ami"

создал, но действие в контекстном меню не появилось

Здравствуйте, Тимофей! Вами используется коробочная деталь или созданная Вами?

От какого окна она наследуется? Производился ли перезапуск/очистка кэша приложения?

"Alimova Anna" написал:

Здравствуйте, Тимофей! Вами используется коробочная деталь или созданная Вами?

От какого окна она наследуется? Производился ли перезапуск/очистка кэша приложения?

С уважением, Анна Алимова

Эксперт III линии технической поддержки Terrasoft


1.созданная мной
2.wnd_BaseGridArea
3.да/да

Добрый день, Тимофей.
Прикрепите, пожалуйста, скриншот вкладки "невизуальные" на котором можно было бы видеть добавляемые элементы меню действия с их параметрами.

Спасибо.

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

Для того чтобы добавить действие «Создать документ на основании договора» в раздел [Договоры] необходимо придерживаться следующего алгоритма:
1. Запустить Terrasoft Administrator.
2. Открыть сервис wnd_ContractsWorkspace. Перейти на закладку «Невизуальные», выделить компонент amiActions. Добавить новый ActionMenuItem:
o1

Заполнить свойства следующим образом:
o2

Сохранить изменения.
3. Перейти на закладку «События». Для добавленного компонента amiDocumentByContract создать обработчик события OnExecute:
o4

В теле функции обработки события прописать код:

FUNCTION amiDocumentByContractOnExecute(ActionMenuItem, Sender) {
         var ContractIDs = BaseWorkspace.Grid.SelectedIDs;
            var Count = ContractIDs.Count;
            IF (!Count||IsDatasetEmpty(dlContracts.Dataset)) {
                        ShowWarningDialog(GridNotContainsAnyRecords);
                        RETURN;
            }
            IF (Count > 1) {
                        var Message = FormatStr(GridContainsSomeRecords, Count);
                        IF (ShowConfirmationDialog(Message) == mrYes) {
                                   CreateDocumentByContract(ContractIDs);
                        }
            } else {
                        CreateDocumentByContract(ContractIDs);
            }
}

В этом же скрипте (wnd_ContractsWorkspaceScript) реализовать функцию FUNCTION CreateDocumentByContract(ContractIDs)

FUNCTION CreateDocumentByContract(ContractIDs) {
            var ContractDataset = dlContracts.Dataset;
            FOR (var i=0; iContractIDs.Count; i++) {
                        var Dataset = Services.GetSingleItemByUSI(ContractDataset.USI);
                        var ContractID = ContractIDs.Items(i);
                        ApplyDatasetIDFilter(Dataset, ContractID, true);
                        Dataset.DisableEvents();
                        Dataset.Open();
                        var DefaultValues = GetNewDictionary();
                        var NamedArray = GetDatasetFieldsValuesNamedArray(Dataset, new Array(
                                   'OwnerID', 'ContactID', 'CampaignID', 'OpportunityID',                            
                                   /* MODULE PROJECTS */ 'ProjectID'/* ENDMODULE PROJECTS */));
                        AddNamedArrayToDictionary(NamedArray, DefaultValues);
                        var InvoiceDate = GetFieldValueFromDisabledField(Dataset, 'StartDate');
                        var ContractID = GetFieldValueFromDisabledField(Dataset, 'ID');
                        Dataset.Close();
                        Dataset.EnableEvents();
                        DefaultValues.ADD('ContractID', ContractID);
                        DefaultValues.ADD('InvoiceDate', InvoiceDate);
                        var Attributes = GetNewDictionary();
                        Attributes('IsCreatedByContractID') = ContractID;
                        CreateNewWindowEdit(Self, 'wnd_DocumentEdit', DefaultValues, Attributes);
                       
            }
}

Таким образом скрипт будет иметь вид:
o5

4. Сохранить все внесенные изменения. Перезапустить приложение Terrasoft. Проверить работу функционала.

Перед внесением изменений в конфигурацию настоятельно рекомендуем создать резервную копию БД.

Нравится

Поделиться

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