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



Задача: добавить на страницу пользовательское поле, значение которого рассчитывается по изменению значения другого поля. Значение должно только отображаться на странице, сохранять его в БД нет смысла (оно строго вычисляется исходя из значений двух других колонок).



Вроде бы все должно работать, и значение поля CalculatedValue должно вычисляться после загрузки страницы и после изменения значений в полях TurnoverF и TurnoverP. Но реально изменение случается только при загрузке страницы - т.е. метод, прописанный в dependencies, не срабатывает. Почему?

entitySchemaName: "UsrTenant",
attributes: {
 "CalculatedValue": {
     dataValueType: Terrasoft.DataValueType.FLOAT,
     dependencies: {
       columns: ["TurnoverF", "TurnoverP"], 
       methodName: "calculateValue"
     }
  }
},
methods: {
  onEntityInitialized: function() {
    this.callParent(arguments);				
    this.calculateValue();
  },
  calculateValue: function() {
    var turnoverF = this.get("TurnoverF");
    if (!turnoverF) {
      turnoverF = 0;
    }
    var turnoverP = this.get("TurnoverP");
     if (!turnoverP) {
       turnoverP = 0;
     }				
    var result = (turnoverP === 0) ? 0 : (turnoverF / turnoverP - 1);
    this.set("CalculatedValue", result);
  }
},
diff : {
//.....................
{
  "operation": "insert",
  "name": "INT_TurnoverF",
  "values": {
    "layout": {
      "colSpan": 12,
      "rowSpan": 1,
      "column": 0,
      "row": 0,
      "layoutName": "Tab7ec5c1bfTabLabelGridLayout4f9aa333"
    },
    "bindTo": "TurnoverF",
    "enabled": true
  },
  "parentName": "Tab7ec5c1bfTabLabelGridLayout4f9aa333",
  "propertyName": "items",
  "index": 0
},
{
  "operation": "insert",
  "name": "INT_TurnoverP",
  "values": {
    "layout": {
      "colSpan": 12,
      "rowSpan": 1,
      "column": 12,
      "row": 0,
      "layoutName": "Tab7ec5c1bfTabLabelGridLayout4f9aa333"
    },
    "bindTo": "TurnoverP",
    "enabled": true
  },
  "parentName": "Tab7ec5c1bfTabLabelGridLayout4f9aa333",
  "propertyName": "items",
  "index": 1
},
{
  "operation": "insert",
  "name": "INTCalculatedValue",
  "values": {
    "caption": "Вычисляемое поле",
    "bindTo": "CalculatedValue",
    "layout": {
      "column": 12, 
      "rowSpan": 1,
      "row": 4, 
      "layoutName": "Header",
      "colSpan": 9
    }
  },
  "parentName": "Header",
  "propertyName": "items",
  "enabled": true,
  "index": 9
},
//.....................
}

 

Нравится

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

Добрый день.

Попробуйте добавить квадратные скобки после dependencies, как на примере ниже:

	"dependencies": [
		{
			"columns": ["Patient"],
			"methodName": "setPatientFieldsValue"
		}
	]

 

Добрый день.

Попробуйте добавить квадратные скобки после dependencies, как на примере ниже:

	"dependencies": [
		{
			"columns": ["Patient"],
			"methodName": "setPatientFieldsValue"
		}
	]

 

Алла Савельева,

как и предполагалось, ошибка была абсолютно дурацкой...

Спасибо!

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

Проблема заключается в том что в LDAP имя и фамилия латиницей указаны отдельно а в displayName указаны латинице. Пользователи хотят видеть кирилицу.

Можно ли в поле "ФИО" совместить через меню настройки LDAP синхронизации два атрибута или там только один может быть?

Нравится

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

Нет, один атрибут синхронизируется с одним полем.

Если всё же планируете разобраться и что-то переделать в механизме синхронизации с LDAP, см. эту и эту темы.

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

Спасибо. Так и реализовано сейчас, через кастомизацию, и как подметил 

Мотков Илья при каждом обновлении приходится проводить адаптацию кода так как он меняется в этом пакете при каждом обновлении

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

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

На нескольких проектах столкнулись со следующей ситуацией.

Описания кейса:



1) Рассмотрим раздел обращения, Колонки "Контакт" и "Контрагент".

Пробуем добавить новый контакт через "Всплывающее действие" при вводе не существующего ФИО в системе.



https://yadi.sk/i/OQCOmeQw3TedkE



В результате при клике на "действие создания" далее откроется миникарточка контакта для заполнения.

Штатный функционал работает корректно.

 

Потребность:

Необходимо добавить сложный фильтр для lookup "Контакта".

Логика фильтра: Если "Контрагент" заполнен, то отображать к выбору только те контакты, у которых на детали "Карьера контакта" (деталь в разделе контакт) есть записи по связанному контрагенту, Который выбран в обращении.



Был выбран способ реализации путём задания фильтра через атрибуты.

"Contact": {
                lookupListConfig: {
                    filters: [
                        function() {
                            var accountId = this.get("Account");
                            var filterGroup = Ext.create("Terrasoft.FilterGroup");
                            if (accountId){
                                var filterById = Terrasoft.createColumnFilterWithParameter(Terrasoft.ComparisonType.EQUAL, "[ContactCareer:Contact].Account", accountId.value);
                                filterGroup.add("filterById", filterById);
                            return filterGroup;
                        }
                    ]
                }
            }



Фильтрация работает корректно.



2) Однако возникла следующая проблема, которой нет при создании фильтров через бизнес-правила:



При указании такого фильтра, пытаемся выполнить шаги пункта (1) по добавлению не существующего в системе контакта и действием вызвать миникарточку.

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



https://yadi.sk/i/4baUZyPr3Tee7E



Есть только возможность выбора из отфильтрованных значений.



https://yadi.sk/i/a-qH6I0R3TefZq

https://www.screencast.com/t/6Mu2hFnkt



Если, согласно условию if, Контрагент не заполнен, то действие для создания появляется.



https://yadi.sk/i/HaQF5U1L3Teg7r



Коллеги, просим подсказать как можно обойти подобное поведение?

Возможно есть простой способ реализации подобного фильтра через бизнес-правила? У нас попросту не получилось организовать подобный фильтр другим способом.

Заранее спасибо!

Нравится

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

Чисто в теории в LookupQuickAddMixin отсекается возможность быстрого создания, если функция checkIsComplicatedFiltersExists вернёт true. Можно прям на странице переопределить эту функцию

checkIsComplicatedFiltersExists: function() {
	return false;
}

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

Варфоломеев Данила,

Спасибо за подсказку! Закрыли задачу!

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

Возник такой вопрос. Как в 7.2 прописать для атрибут смены фокуса для поля:

bankModuleUtils.getTextEdit("DocumentSeries", {
value: {
bindTo: "DocumentSeries"
},
enabled: {
bindTo: "IsEnabled"
}
})

И вообще как можно увидеть весь список доступных атрибутов для этих контролов?

Нравится

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

Добрый день!

Есть булевый атрибут focused - признак получения элементом фокуса. Вы его имеете в виду? Необходимо просто добавить его в конфигурацию создаваемого контрола и указать ему значение или привязку к атрибуту модели (который предварительно добавить в модель):

bankModuleUtils.getTextEdit("DocumentSeries", {
	value: {bindTo: "DocumentSeries"},
	enabled: {bindTo: "IsEnabled"},
	focused: true
})

или

bankModuleUtils.getTextEdit("DocumentSeries", {
	value: {bindTo: "DocumentSeries"},
	enabled: {bindTo: "IsEnabled"},
	focused: {bindTo: "IsFocused"}
})

Увидеть все доступные свойства и методы проще всего в отладчике. К примеру, установите точку останова на инициализации какой-либо страницы и выполните в консоли код:

var newTextEdit = Ext.create("Terrasoft.TextEdit");

После этого в переменной newTextEdit можно будет увидеть все свойства и методы контрола TextEdit.

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

Задача
В БП проверить контрагента в базе по реквизитам и дальше заполнить реквизиты нового заказчика, если такого нет в базе.

(требование клиента)
Через сервис окна в Terrasoft запрашиваются реквизиты у пользователя :
- Наименование;
- Регион;
- Город;
- Телефон;

Создаем форму wnd_name_reg_city_phone унаследуем ее от wnd_BaseEdit, в Невизуальные компоненты добавляем даталинки на справочники датасетов ds_City и ds_State. Добавляем 4 ре контрола два из них LookupControl (для выбора справочников, заметьте НЕ LookupDataControl) и два Edit контрола.

edtName – Edit возвращает значение текст
edtState – LookupControl возращает ID выбранного региона
edtCity – LookupControl возращает ID выбранного города
edtPhone - возвращает значение текст

Получаем следующую форму (сама форма в прикрепленных файлах)
1
Далее для того что бы считывать логику необходимо подключить (создать) к окну скрипт. Выберете контрол Ok, событие OnClick два раза кликните на колонку Значение, дальше дизайнер предложить вам создать скрипт

На событие Ок, пропишем логику считывания значений, и запись их в атрибуты окна, для последующей передачи их в БП

//-----------------------------------------------------------------------------
// wnd_name_reg_city_phoneScript
//-----------------------------------------------------------------------------


function btnOKOnClick(Control) {

var AccountName = edtName.Value;
var AccountStateID = edtState.Value;
var AccountCityID = edtCity.Value;
var AccountPhone =  edtPhone.Value

SetAttribute(Control.ParentWindow, 'AccountName',AccountName);
SetAttribute(Control.ParentWindow, 'AccountStateID',AccountStateID);
SetAttribute(Control.ParentWindow, 'AccountCityID',AccountCityID);
SetAttribute(Control.ParentWindow, 'AccountPhone',AccountPhone);
         SendNotify(Control.ParentWindow, MSG_OK);
}


function Main() {
         var Window = Services.GetNewItemByUSI('wnd_name_reg_city_phone');
         Window.IsDesigning = false;        
         Window.Prepare();
         Window.Show();      
}

function Main() в данном коде необходима для реализации возможности и вызова окна по нажатию F9
Создаем БП
В БП следует создать параметры
2
Элемент Открытие окна в следующем варианте с следующими опциями
3

4
Каждый из параметров должен быть установлен с следующей опцией
5
6
Предварительный вид БП будет следующим видом
7
Элемент scr это скрипт, в котором мы считаем параметры с Окна, и запустим хранимую процедуру Базы данных, которая реализует выборку из базы по условию:

(требование клиента)
Name содержит N &
StateID содержит P &
CityID содержит G &
(Communication1 содержит T) или (Communication2 содержит T) или (Communication3 содержит T) или (Communication4 содержит T) или (Communication5 содержит T)

Хранимая процедура будет иметь вид:

CREATE  procedure [dbo].[tsp_check_name_reg_city_phone]
      @AccountName nvarchar(250),
      @AccountStateID uniqueidentifier ,
      @AccountCityID uniqueidentifier,
      @AccountPhone nvarchar(250),
      @Result int output
  AS
begin
      declare @AccountNameLike nvarchar(300)
      declare @AccountPhoneLike nvarchar(300)
     
    SET @AccountNameLike = '%'+ @AccountName + '%';
    SET @AccountPhoneLike= '%'+ @AccountPhone + '%';


DELETE FROM  tbl_Account_b;

INSERT INTO [dbo].[tbl_Account_b]
SELECT [ID]
      ,[CreatedOn]
      ,[ModifiedOn]
      ,[Name]
      ,[CreatedByID]
      ,[ModifiedByID]
      ,[OfficialAccountName]
      ,[PrimaryContactID]
      ,[TerritoryID]
      ,[AnnualRevenue]
      ,[EmployeesNumber]
      ,[OwnerID]
      ,[CampaignID]
      ,[AddressTypeID]
      ,[Address]
      ,[CityID]
      ,[StateID]
      ,[ZIP]
      ,[CountryID]
      ,[ActivityID]
      ,[FieldID]
      ,[Communication1]
      ,[Communication2]
      ,[Communication3]
      ,[Communication4]
      ,[Communication5]
      ,[Communication1TypeID]
      ,[Communication2TypeID]
      ,[Communication3TypeID]
      ,[Communication4TypeID]
      ,[Communication5TypeID]
      ,[Description]
      ,[AccountTypeID]
      ,[Code]
      ,[TaxRegistrationCode]
      ,[SettledCredit]
      ,[PostponementPayment]
FROM [dbo].[tbl_Account]
WHERE [Name] LIKE @AccountNameLike
AND [StateID] = @AccountStateID
AND [CityID] = @AccountCityID
AND (
   [Communication1] LIKE @AccountPhoneLike
OR [Communication2] LIKE @AccountPhoneLike
OR [Communication3] LIKE @AccountPhoneLike
OR [Communication4] LIKE @AccountPhoneLike
OR [Communication5] LIKE @AccountPhoneLike
)

 SET @Result = (SELECT count(*) FROM  [dbo].[tbl_Account_b]);

end  

Возращает процедура количество записанных данных.

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

SELECT * INTO tbl_Account_b FROM tbl_Account WHERE 1 = 0

Дальше в БП мы должны вызвать данную процедуру.

В элементе scr в БП пишем код (предварительно подключив скрипты scr_DB, scr_WindowUtils,scr_WorkflowUtils)
9

function Item3OnExecute(ScriptItem, IsComplete) {
var vAccountNameBP = WFGetParamValue(ScriptItem.ParentItems.ParentDiagram, 'AccountNameBP');
var vAccountStateIDBP = WFGetParamValue(ScriptItem.ParentItems.ParentDiagram, 'AccountStateIDBP');
var vAccountCityIDBP = WFGetParamValue(ScriptItem.ParentItems.ParentDiagram, 'AccountCityIDBP');
var vAccountPhoneBP = WFGetParamValue(ScriptItem.ParentItems.ParentDiagram, 'AccountPhoneBP');


var Parameters = CreateSPParameters();
CreateSPParameter(Parameters, 'AccountName', pdtString, vAccountNameBP);
CreateSPParameter(Parameters, 'AccountStateID', pdtString, vAccountStateIDBP);
 CreateSPParameter(Parameters, 'AccountCityID', pdtString, vAccountCityIDBP);
CreateSPParameter(Parameters, 'AccountPhone', pdtString, vAccountPhoneBP);

CreateSPParameter(Parameters, 'OutTest', pdtInteger, 0);
Parameters.ItemsByName('OutTest').ParamType = 1;

var SQLText =
'exec dbo.tsp_check_name_reg_city_phone :AccountName, :AccountStateID, :AccountCityID,:AccountPhone,:OutTest OUTPUT';
Connector.DBEngine.ExecuteCustomSQL(SQLText, Parameters);

var res = Parameters.ItemsByName('OutTest').ValAsInt;
WFSetParamValue(ScriptItem.ParentItems.ParentDiagram, 'Acc_count', res);  
}

В строчках WFSetParamValue(ScriptItem.ParentItems.ParentDiagram, 'Acc_count', res);
Мы записываем полученное значение с процедуры в параметр БП 'Acc_count', после чего в элементе test_res в качестве примера выводим полученное значение.

Дальше по параметру 'Acc_count' можно анализировать значение переменной, и в зависимости от этого создавать нового контрагента

Окончательный вид всех параметров БП
9
Все сервисы прикреплены к данному сообщению

Нравится

Поделиться

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

Алексей, почему вы используете varchar вместо nvarchar? Вы потеряете юникод.
Создавать таблицу tbl_Account_b лучше запросом:

SELECT * INTO tbl_Account_b FROM tbl_Account Where 1 = 0

Таким образом у вас tbl_Account_b будет пустая, а не содержать всех Контрагентов.

Александр, спасибо за замечания, исправил предыдущий пост.

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

Вопрос следующий. Какие атрибуты поддерживает Report и ReportPreviewer? Нигде не смог найти :(

Нравится

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

Добрый день, Дмитрий!

В файле TSReportLibrary.idl, заархивированном и прикрепленном к сообщению, содержится IDL (описание свойств и методов) для интерфейсов классов, используемых при построении отчетов, в т.ч. IReport и IReportPreviewer. Содержимое файла поможет Вам определить состав свойств и методов интересующих классов.

Желаю успехов!

Вообще есть много инструментов, которые позволяют выковырять описание библиотеки типов из dll (это иногда очень помагает, так как SDK не всегда в актуальном состоянии). Например, мой Total Commander по F3 показывает интерфейсы, объявленные в dll. Причем плагинов я не доставлял.

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