Добрый день!

Возникла потребность добавить в Email сообщение подпись (не до хорошего - чего уж там, не персонализированную, а хотя бы универсальную для всех пользователей). Нашел вот такой вариант решения: https://community.terrasoft.ru/blogs/7765
Как я понимаю, для 7.7 он уже не актуален. Так? Есть ли, в таком случае, возможность добавить подпись в e-mail сообщение для bpm'online 7.7?

Нравится

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

Здравствуйте, Николай!

Инструкция актуальна и для версии 770. Для решения Вам необходимо установить за поле htmlBody значение по умолчанию (которое и будет являться подписью). Изображения не обязательно хранить в БД - их можно вставлять как ссылку на изображение через тег

Нет там HtmlBody. А с просто Body такой фокус не прокатывает.

Странно!

В значение по умолчанию (константа) добавил следующий текст:

<br><br><br>С уважением,<br>очень большой смайлик:<br><img src =""https://upload.wikimedia.org/wikipedia/commons/8/85/Smiley.svg"">

Очистил кеш браузера (вот это очень нужно сделать).

Результат

Удалось конкретизировать проблему. У меня подпись - это картинка, но не ссылкой на внешний ресурс, а в фомате Base64.

<img src="""" mc:label=""Image"" alt=""Image"" width=""355"" class=""flexible-image"" style=""max-width:96px;width:96px;height:76px;display:block;border:none;margin:0;padding:0;"" mc:edit=""Image"">

В окне создания нового письма она отображается корректно. Но, когда получатель открывает мое письмо, он видит только alt. Параметр src вообще отсутствует.

Что интересно, если показать источник, то там src c base64 присутствует.

Здравствуйте, Николай!

Используйте ссылку на внешний ресурс и все будет работать.

Алексей, Вы серьезно?!

Вот, я получаю e-mail сообщения от сотрудников Terrasoft. Во всех этих письмах есть графические объекты. И это не ссылки! Это именно base64 объекты. Отсюда вопрос: сотрудники компании пользуются для отправки e-mail не свой программный продукт, а сторонние решения?! Или, все-таки свой? Тогда вопрос - как добиться такого же эффекта?

Здравствуйте, Николай!

Передали в отдел разработки для анализа. Результат сообщим в рамках тех. поддержки и здесь отдельным сообщением.

А есть возможность встроить какой-то HTML-редактор, чтобы пользователи могли написать себе подписи сами?

"Владимир Соколов" написал:

А есть возможность встроить какой-то HTML-редактор, чтобы пользователи могли написать себе подписи сами?

Владимир, добрый день!

Данный вопрос рассмотрен и такая возможность присутствует в backlog'е департамента разработки для реализации в будущих версиях приложения.

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

Всем привет.

Используется BPMonline Bank Sales Версия 7.5.0.1275
Возникает проблема с параметром процесса типа Коллекция. Диаграмма процесса приложена.

В первом сценарии делаем выборку данных и результирующую коллекцию присваиваем параметру процесса. Во втором сценарии достаем нужную информацию из выборки через Entity, которую, в свою очередь, вытаскиваем из коллекции по индексу. Сам индекс инкрементируем в Формуле и проверяем не превысил ли он количество элементов в выборке. Так вот, первый шаг проходит хорошо. Все данные достаются и показаны в окне Проверка результата и соответствуют действительности. Но при заходе на второй круг в элементе-сценарии Формирования текста SMS и номера возникает ошибка

System.ArgumentOutOfRangeException: Specified argument was out of the range of valid values.
Parameter name: Значение индекса находится вне допустимого диапазона значений
   at Terrasoft.Core.Entities.EntityCollection.FindNodeByIndex(Int32 index)
   at Terrasoft.Core.Process.BirthdayQuery.ScriptTask2Execute(ProcessExecutingContext context)
   at Terrasoft.Core.Process.ProcessFlowElement.Execute(ProcessExecutingContext context)

Индекс при этом равен 1. То есть, от коллекции, похоже, осталась только одна запись.

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

Код сценария Выборка данных у кого ДР

        var esqBirthdays = new EntitySchemaQuery(UserConnection.EntitySchemaManager, "Contact");
        contactIdFieldName = esqBirthdays.AddColumn("Id").Name;
        esqBirthdays.AddColumn("GivenName");
        esqBirthdays.AddColumn("MiddleName");
               
        esqBirthdays.IsDistinct = true;
                       
        //Получение сегодняшней даты
         today = DateTime.Today;
       
        var esqMacrosTypeMonth = EntitySchemaQueryMacrosType.Month;
        var esqFilterByMonth = esqBirthdays.CreateFilter(FilterComparisonType.Equal, "BirthDate", esqMacrosTypeMonth, today.Month);
        esqBirthdays.Filters.Add(esqFilterByMonth);
               
        var esqMacrosTypeDay = EntitySchemaQueryMacrosType.DayOfMonth;
        var esqFilterByDayToday = esqBirthdays.CreateFilter(FilterComparisonType.Equal, "BirthDate", esqMacrosTypeDay, today.Day);
        esqBirthdays.Filters.Add(esqFilterByDayToday);
       
        //Есть моб тел?
        var esqFilterWithMobilePhone = esqBirthdays.CreateFilterWithParameters(FilterComparisonType.Equal, "[ContactCommunication:Contact].CommunicationType", new Guid("F039972E-470E-457F-9B77-65054B3534B0"));
        esqBirthdays.Filters.Add(esqFilterWithMobilePhone);
       
        //Выполнение запроса и получение результирующей коллекции
        entitiesBD = esqBirthdays.GetEntityCollection(UserConnection);
    numberOfentitiesBDInCollection = entitiesBD.Count;
        currentIndexBD = 0;
        esqSqlText = esqBirthdays.GetSelectQuery(UserConnection).GetSqlText();
               
        return true;

Код сценария Формирования текста СМС и номера

        Entity element = entitiesBD[currentIndexBD];
        Guid contactID = element.GetTypedColumnValueGuid>(contactIdFieldName);
    string contactName = element.GetTypedColumnValuestring>("GivenName");
        string contactMiddleName = element.GetTypedColumnValuestring>("MiddleName");
        string BirthDateText = DateTime.Today.ToString("dd MMMM");
        string messageText = "Дорогой(ая) "+contactName+"! Росинбанк поздравляет Вас с Днем Рождения "+BirthDateText+"  и желает Вам всех благ! Росинбанк";
        if(contactMiddleName!=null) messageText = "Дорогой(ая) "+contactName+" "+contactMiddleName+"! Росинбанк поздравляет Вас с Днем Рождения "+BirthDateText+"  и желает Вам всех благ! Росинбанк";
        SMSTextBD = messageText;
       
        var contactComm = new EntitySchemaQuery(UserConnection.EntitySchemaManager, "ContactCommunication");
        var contacctNumberFieldName = contactComm.AddColumn("Number").Name;
       
        var esqFilter1 = contactComm.CreateFilterWithParameters(FilterComparisonType.Equal, "Contact", contactID);
        contactComm.Filters.Add(esqFilter1);
       
        var esqFilter2 = contactComm.CreateFilterWithParameters(FilterComparisonType.Equal, "CommunicationType", new Guid("F039972E-470E-457F-9B77-65054B3534B0"));
        contactComm.Filters.Add(esqFilter2);
       
        var mobilePhoneCollection = contactComm.GetEntityCollection(UserConnection);
        if(mobilePhoneCollection.Count>0)
        {
        phoneNumberBD = mobilePhoneCollection[0].GetTypedColumnValuestring>(contacctNumberFieldName);
        } else
        {
        phoneNumberBD = "No number";
        }
       
        //var SMSObject = new SendSMSClass(SMSServiceAddress);
        //SMSObject.SendSMS(phoneNumber, messageText);

return true;   
csharp>

Нравится

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

Добрый день!
Попробуйте выполнять проверку и автоинкремент индекса в элементе “Задание сценарий”. Например,

if(IndexBD < entitiesBD.Count){
...
IndexBD++;
} else {
...
}
return true;

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

Добрый день!

Как сделать в 7.6, чтобы при сохранении любой карточки, не происходило выхода из неё (а выход осуществлялся по Close), в том числе, если карточка открывается в ходе БП?

Нравится

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

Владимир, здравствуйте!

За данное действие отвечает параметр isSilent».
Пример реализации Вы может посмотреть в схеме «LeadQualificationPageV2».

Также рекомендую ознакомиться со следующими топиками:
- http://www.community.terrasoft.ru/forum/topic/12346;
- http://www.community.terrasoft.ru/forum/topic/11623;
- http://www.community.terrasoft.ru/forum/topic/12063.

изменили метод onSaved:

onSaved: function (response, config) {
     if (!this.get("IsProcessMode")) {
                     if (config) {
       if (!config.isSilent) {
                       var updateConfig = this.getUpdateDetailOnSavedConfig();
        this.sandbox.publish("UpdateDetail", updateConfig, [this.sandbox.id]);
                       config.isSilent = true;
       }
                     }
                     else {
                   var updateConfig = this.getUpdateDetailOnSavedConfig();
       this.sandbox.publish("UpdateDetail", updateConfig, [this.sandbox.id]);
                         config = { isSilent: true};
                     }
     }
                    this.callParent(arguments);
    },

Этот код запускается только если карточка открыта не в ходе процесса. Если то же самое делать в процессе (без проверки), то при нажатии на Save, кнопка Save всё равно остается активной (и не показывается Close)

Как реализовать данную задачу для работы Save-Close в процессах?

Подскажите а какую карточку вы вызываете в ходе БП, не преднастроеную ведь?

Обычные карточки - Контрагент, Продажа, Счет, Документ.

У пользователей есть прекрасная привычка сохранять по ходу работы (лучше 5 раз нажать Save, чем потом снова 30 минут вводить всю информацию). Но после первого же сохранения система считает, что работа выполнена и бежит дальше по процессу. Очень неудобно. Было бы хорошо закрывать карточку и идти дальше именно по Close

При сохранении записи в бд, в любом случае БП это поймет, и побежит дальше по процессу.
Данное поведение поменять нельзя.
Другое дело пользователь останется в карточке, если сохранение было в isSilent, и сможет довносить изменения.
А активность кнопки Save определяется в методе updateButtonsVisibility (BasePageV2), переопределяя его, в наследнике BasePageV2, в теории можно и поменять поведение отображения.

Владимир Соколов,   

В итоге нашли решение этой проблемы? В данный момент столкнулись с той же задачей.

Дарина,

Искали, но наткнулись на кучу других проблем, связанных с бизнес-процессами

Создал идею, но пока нет отклика - https://community.terrasoft.ua/ideas/save-i-saveclose

Наверное, недостаточно актуальности :(

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

Привет всем!!!

всем кто пользуется браузером Chrome и автоматически успел обновиться до версии 48. После обновления я у себя обнаружил что перестали работать Диаграммы и Бизнес-Процессы. Всему виной что компания Google в 48 версии Хрома отказались в API от функционала SVGPathSeg. Для того чтобы все работало делаем следующее:
1. Из вложения сохраняем архив pathseg-master.zip
2. В каталоге ...\BPMOnlineSalesEnterpriseMarketingServiceEnterprise7_7_0.Site\Terrasoft.WebApp\Resources\ui создаем каталог pathseg и сохраняем в него файл pathseg.js
3. редактируем файл core-modules-object.js расположенный по пути ...\BPMOnlineSalesEnterpriseMarketingServiceEnterprise7_7_0.Site\Terrasoft.WebApp\Resources\ui\Terrasoft\amd
4. в файл core-modules-object.js добавляем следующее:

        "pathseg": {
                "path": "pathseg",
                "exports": "pathseg",
                "external": true,
                "separateFromBuild": true
        },

в данном же файле находим тег "ej-diagram" и изменяем его, должно получиться вот так:
        "ej-diagram": {
                "path": "Syncfusion",
                "exports": "ej",
                "external": true,
                "deps": ["ej-common-all", "jsrender", "pathseg"],
                "css": ["ej-diagram"],
                "separateFromBuild": true
        },

5. Выполняем очистку Истории в браезере, Выполняем очистку Redis-a

Заходим в BPMOnline и наслаждаемся, что все работает :)

Нравится

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

Здравствуйте, Михаил!

Мой браузер также автоматически обновился до версии 48.0.2564.97. При этом дизайнер процессов в bpm'online 770 работает корректно.

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

Алексей, кажется вы знаете какой-то секрет про ej-diagram :wink:

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

Здравствуйте.

Версия 7.7.0.2293

В Terrasoft.WebApp\DesktopBin\WorkspaceConsole\ запустил PrepareWorkspaceConsole.x64.bat
Прописал правильный connectionStrings в Terrasoft.Tools.WorkspaceConsole.exe.config
Выгружаю изменения командой Terrasoft.Tools.WorkspaceConsole.exe -operation=SaveDBContent -workspaceName=Default -destinationPath=D:\Work\Repository\Kapital -contentTypes=Repository

Появляется ошибка "Object reference not set to an instance of an object" (скрин во вложение)

Конфигурация успешно компилируется. Сайт работает.

Подскажите как узнать в какой схеме проблема и что нужно сделать что бы ее исправить?

Нравится

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

Добрый день.
Возможно не все файлы скопировались из папки
..\Terrasoft.WebApp\bin
Попробуйте скопировать в ручном режиме с полной заменой

"Пащенко Александр Сергеевич" написал:

Добрый день.

Возможно не все файлы скопировались из папки

..\Terrasoft.WebApp\bin

Попробуйте скопировать в ручном режиме с полной заменой

Скопировал все вручную, не помогло.

Здравствуйте.
В "Terrasoft.Tools.WorkspaceConsole.exe.config" кроме самих настроек подключения есть секция параметров:

<db>
      <general connectionStringName="mssqlDB" securityEngineType="Terrasoft.DB.MSSql.MSSqlSecurityEngine, Terrasoft.DB.MSSql" executorType="Terrasoft.DB.MSSql.MSSqlExecutor, Terrasoft.DB.MSSql" engineType="Terrasoft.DB.MSSql.MSSqlEngine, Terrasoft.DB.MSSql" metaEngineType="Terrasoft.DB.MSSql.MSSqlMetaEngine, Terrasoft.DB.MSSql" metaScriptType="Terrasoft.DB.MSSql.MSSqlMetaScript, Terrasoft.DB.MSSql" typeConverterType="Terrasoft.DB.MSSql.MSSqlTypeConverter, Terrasoft.DB.MSSql" binaryPackageSize="1048576" currentSchemaName="dbo" />
    </db>

там есть параметр general connectionStringName="mssqlDB" . Параметры подключения должны быть указаны именно в этой connectionString (кроме mssqlDB ещё есть db).

Александр, спасибо.

Помогло.

"Котенко Александр" написал:Параметры подключения должны быть указаны именно в этой connectionString

либо можно использовать
"инструкция)" написал:
webApplicationPath
Путь к веб-приложению, из которого будет вычитана информация по соединению с БД
Необязательный параметр. Если не указан - соединение будет установлено с базой, указанной в строке соединения в файле App.Config приложения. Если указан - соединение будет установлено с БД из файла ConnectionStrings.config веб-приложения
Используется для всех операций, в которых участвует БД

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

Здравствуйте.

Подскажите, как использовать события нажатия кнопок в текстовом поле.
Объявлено текстовое поле:

//diff
{
"operation": "insert",
"parentName": "Header",
"propertyName": "items",
"name": "Surname",
"values": {
   "layout": { "column": 0, "row": 0, "colSpan": 7},
   "bindTo": "Cyr_Surname",
    "contentType": Terrasoft.ContentType.TEXT,
    "caption": {"bindTo": "Resources.Strings.Cir_SurnameCaption"}
}
}

attributes: {
   "Surname": {
    dataValueType: Terrasoft.DataValueType.TEXT
    }
}

Как обратиться к событиям OnKeyUp, OnKeyDown? В итоге должно получиться: Пользователь вводит текст, нажимает Enter, выполняется моя функция.

Нравится

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

Олег, если правильно понимаю, то вот здесь - http://www.community.terrasoft.ru/forum/topic/11415 подобное уже обсуждалось.

Здравствуйте, Илья.
Сделал как сказано в указанной ссылке. Выходит ошибка в консоль: "TypeError: a.target is null" И соответственно не работает.

Вот, что написал:

init: {
 
var map = new Ext.util.KeyMap({
   target: "RIBClientSearchPageCyr_SurnameTextEdit-el", 
   key: 13, // or Ext.EventObject.ENTER
   scope: this,
   binding: map,
   fn: this.OnMyPressEnter
});
 
this.callParent(arguments);
 
}
 
onMyPressEnter: function(args) {
	this.showInformationDialog("Test");
	if (this.keyMap) {
	this.keyMap.destroy();
	this.keyMap = null;
	}
},

Подскажите, что не так. Спасибо.

На момент начала события init, Ext компоненты(текстовое поле) еще нет, делайте так:

onEntityInitialized: function() {
   this.callParent(arguments);
 
   var map = new Ext.util.KeyMap({
      target: "AccountPageV2CodeTextEdit-el",
      key: Ext.EventObject.ENTER,
      fn: this.myHandler,
      scope: this
   });
},
myHandler: function() {
   alert("ENTER");
},

То есть, инициализируйте подписку в функции onEntityInitialized

Сделал в onEntityInitialized. На нажатие ENTER среагировал новой ошибкой. В консоле: message: TypeError: k is undefined в файле all-combined.js Нашел функцию в all-combined.js, в которой вызывается ошибка. В строке if (k.call(l, h, a) !== true && b).

processEvent: Ext.identityFn,
    processBinding: function(g, a) {
        if (this.checkModifiers(g, a)) {
            var h = a.getKey(), k = g.fn || g.handler, l = g.scope || this, j = g.keyCode, b = g.defaultEventAction, c, e, d = new Ext.EventObjectImpl(a);
            for (c = 0,
            e = j.length; c < e; ++c) {
                if (h === j[c]) {
                   if (k.call(l, h, a) !== true && b) {
                        d[b]()
                    }
                    break
                }
            }
        }
    },

Чего-то не хватает еще.

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

Ребят, спасибо разобрался. Подвожу итог:

onEntityInitialized: function() {
	this.callParent(arguments);
 
	var keyMap =  new Ext.util.KeyMap({
		target: "RIBClientSearchPageCyr_SurnameTextEdit-el",
		key: Ext.EventObject.ENTER,
		fn: this.onMyPressEnter,
		scope: this,
		binding: keyMap
	});
},
 
onMyPressEnter: function() {
	this.showInformationDialog("Test");
},

И все работает.

Разумеется, javascript то case sensitive, а k = g.fn андефайнд должен был намекнуть что функцию не находит. А не находило ее ибо регистр первой буквы был разный :wink:

Все так, все так :-)

Есть еще один момент, который хотелось бы уточнить. Возможно, кому-то пригодится. Иногда нужно, что бы функция выполнилась просто по нажатию клавиши на странице, не обязательно в конкретном поле. Собрав все данные, вот что у меня получилось:

onEntityInitialized: function() {
	this.callParent(arguments);
 
	this.keyMap = null;
 
	var map =  new Ext.util.KeyMap(Ext.getBody(), [{
		key: Ext.EventObject.ENTER,
		fn: this.onMyPressEnter,
		scope: this,
		binding: map
	}]);
 
	this.keyMap = map;
 
},
 
onMyPressEnter: function() {
	this.showInformationDialog("Test");
 
//Функция выполнится один раз. Нужно использовать при переходе по процессу	
	if (this.keyMap) {
		this.keyMap.destroy();
		this.keyMap = null;
	}
}, 
Показать все комментарии

Есть две базы - тестовая и рабочая. Подскажите пожалуйста как быстро и безболезненно перенести новый функционал из тестовой на рабочую. Базы находятся на разных физических серверах(тестовая база ранее была скопирована с рабочей).
Дайте пожалуйста ссылку на пошаговую инструкцию.

Нравится

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

и не только функционал, но и наполнение некоторых справочников и системных значений (и не всех, а только тех, которые указать)

Здравствуйте.
1) Если планируется переносить пакеты между workspace-ами или между БД, то в этом случае необходимо начинать разработку с подключенной системой контроля версий (SVN).
2) Все доработки в пакетах сохраняются в SVN.
3) После завершения разработки пакета и исправления всех ошибок, пакет может устанавливаться на рабочую БД.
4) Для того, чтоб с пакетом установились так же наполнение справочников и системных настроек, эти данные должны быть привязаны к пакету как данные пакета.
Как работать с системой контроля версий (SVN), можно почитать здесь: http://academy.terrasoft.ru/documents/?product=SDK&ver=7.6.0

Если разработка велась без SVN, то единственные вариант, это выгрузка пакетов из тестовой БД в zip архив
Пример:
Terrasoft.Tools.WorkspaceConsole.exe -operation=SaveDBContent -workspaceName=Default -destinationPath=D:\Temp\Repository\ -contentTypes=Repository -logPath=D:\Temp\WorkspaceConsoleLog

и загрузка zip архива на рабочую БД
Пример:
Terrasoft.Tools.WorkspaceConsole.exe -workspaceName=Default -operation=InstallFromRepository -sourcePath=d:\Temp\Repository\ -destinationPath=D:\Temp\Destination\ -continueIfError=true -logPath=D:\WorkspaceConsoleLog

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

"Котенко Александр" написал:если данные не привязывались к пакету, наполнение справочников и системных настроек нужно будет переносить в ручном режиме.

а как их привязать к пакету?

У нас с workspace console получилось наоборот - перенеслись абсолютно все данные, даже тестовые записи и логи :(

"Владимир Соколов" написал:а как их привязать к пакету?

В конфигурации на вкладке данные выбираете объект, тип установки(в большинстве случаев необходимо выбирать "установка") и фильтрацию, затем нажимаете кнопку "Показать данные", видите результат и сохраняете его, если все ок.

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

Здравствуйте. При настройке колонок реестра "Документы" не могу добавить именно контакт, в конце всегда только пишется количество, дата создания и т.д. Подскажите как отобразить нужные мне данные?
Вот путь: Документ.Активность по колонке документ. Список участников согласования....а внутри только несколько строк и ни слова о самом согласующем
Благодарю

Нравится

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

Здравствуйте!

По одному документу может быть несколько активностей с разными контактами. У каждой активности свой список участников согласования (участников так же может быть несколько). В таком случае непонятно какой контакт выводить в реестр. Для решения рекомендую добавить в раздел "Документы" поле "Согласующий" (справочник "Контакты") и выводить в реестр именно его.

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

Здравствуйте. Возникла такая вот потребность делать все изменения с документами, не открывая каждый документ отдельно. Всё это делать в реестре страницы: изменить даты, ответственного, номер, название и т.д. Не изменять сами колонки, а делать изменения именно в них. Возможно ли такая настройка реестра?
Благодарю

Нравится

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

Сразу назову общее ограничение - количество колонок в реестре довольно ограничено, а количество полей в карточке - нет

"Владимир Соколов" написал:

Сразу назову общее ограничение - количество колонок в реестре довольно ограничено, а количество полей в карточке - нет


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

Здравствуйте, Дмитрий Юрьевич.

Вот пример кода для раздела "Документы":

define("DocumentSectionV2", ["VisaHelper", "BaseFiltersGenerateModule",	"DocumentSectionGridRowViewModel",
	"ConfigurationGrid", "ConfigurationGridGenerator", "ConfigurationGridUtilities"],
	function(VisaHelper, BaseFiltersGenerateModule) {
		return {
			entitySchemaName: "Document",
			mixins: {
				ConfigurationGridUtilities: "Terrasoft.ConfigurationGridUtilities"
			},
			 attributes: {
        		"IsEditable": {
            		dataValueType: Terrasoft.DataValueType.BOOLEAN,
            		type: Terrasoft.ViewModelColumnType.VIRTUAL_COLUMN,
            		value: true
         		}
      		},
			methods: {
				getGridRowViewModelClassName: function() {
					if (this.getIsEditable()) {
						return this.getEditableGridRowViewModelClassName(arguments[0]);
					} else {
						return this.callParent(arguments);
					}
				},
				onActiveRowAction: function(buttonTag, primaryColumnValue) {
					this.mixins.ConfigurationGridUtilities.onActiveRowAction.apply(this, arguments);
				}
			},
			diff: /**SCHEMA_DIFF*/[
				{
					"operation": "merge",
					"name": "DataGrid",
					"values": {
						className: "Terrasoft.ConfigurationGrid",
						generator: "ConfigurationGridGenerator.generatePartial",
						generateControlsConfig: {bindTo: "generateActiveRowControlsConfig"},
						changeRow: {bindTo: "changeRow"},
						unSelectRow: {bindTo: "unSelectRow"},
						onGridClick: {bindTo: "onGridClick"},
						initActiveRowKeyMap: {bindTo: "initActiveRowKeyMap"},
						activeRowAction: {bindTo: "onActiveRowAction"},
					}
				},
 
				{
					"operation": "insert",
					"name": "DataGridActiveRowSaveAction",
					"parentName": "DataGrid",
					"propertyName": "activeRowActions",
					"values": {
						"className": "Terrasoft.Button",
						"style": this.Terrasoft.controls.ButtonEnums.style.TRANSPARENT,
						"tag": "save",
						"markerValue": "save",
						"imageConfig": {"bindTo": "Resources.Images.SaveIcon"}
					}
				},
 
				{
					"operation": "insert",
					"name": "DataGridActiveRowCancelAction",
					"parentName": "DataGrid",
					"propertyName": "activeRowActions",
					"values": {
						"className": "Terrasoft.Button",
						"style": this.Terrasoft.controls.ButtonEnums.style.TRANSPARENT,
						"tag": "cancel",
						"markerValue": "cancel",
						"imageConfig": {"bindTo": "Resources.Images.CancelIcon"}
					}
				},
 
				{
					"operation": "insert",
					"name": "DataGridActiveRowRemoveAction",
					"parentName": "DataGrid",
					"propertyName": "activeRowActions",
					"values": {
						"className": "Terrasoft.Button",
						"style": this.Terrasoft.controls.ButtonEnums.style.TRANSPARENT,
						"tag": "remove",
						"markerValue": "remove",
						"imageConfig": {"bindTo": "Resources.Images.RemoveIcon"}
					}
				}
			]/**SCHEMA_DIFF*/
		};
	});

Результат:

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

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

Нравится

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

Добрый день. Обратите внимание,что в OrderPageV2 еще есть следующий код

	getActions: function() {
						var actionMenuItems = this.callParent(arguments);
						actionMenuItems.add("SendToVisaSeparator", this.getActionsMenuItem({
							Type: "Terrasoft.MenuSeparator",
							Caption: ""
						}));
						actionMenuItems.add("SendToVisa", this.getActionsMenuItem({
							"Caption": VisaHelper.resources.localizableStrings.SendToVisaCaption,
							"Tag": VisaHelper.SendToVisaMenuItem.methodName,
							"Enabled": {"bindTo": "canEntityBeOperated"}
						}));
						return actionMenuItems;
					},
 
					/**
					 * Действие "Отправить на визирование"
					 */
					sendToVisa: VisaHelper.SendToVisaMethod,

а также в OrderSectionV2

define("OrderSectionV2", ["ProductSalesUtils", "BaseFiltersGenerateModule", "VisaHelper", "ReportUtilities",
	"css!VisaHelper"], function(ProductSalesUtils, BaseFiltersGenerateModule, VisaHelper) {
	return {
		entitySchemaName: "Order",
		attributes: {
			/**
			 * Заголовок пункта меню "Отправить на визирование"
			 */
			SendToVisaMenuItemCaption: {
				dataValueType: Terrasoft.DataValueType.TEXT,
				value: VisaHelper.resources.localizableStrings.SendToVisaCaption
			}
		},
		methods: {
 
			/**
			 * Действие "Отправить на визирование"
			 */
			sendToVisa: VisaHelper.SendToVisaMethod,
 
			/**
			 * Возвращает коллекцию действий раздела в режиме отображения реестра
			 * @protected
			 * @overridden
			 * @return {Terrasoft.BaseViewModelCollection} Возвращает коллекцию действий раздела в режиме
			 * отображения реестра
			 */
			getSectionActions: function() {
				var actionMenuItems = this.callParent(arguments);
				actionMenuItems.addItem(this.getActionsMenuItem({
					Type: "Terrasoft.MenuSeparator",
					Caption: ""
				}));
				actionMenuItems.addItem(this.getActionsMenuItem({
					"Caption": {bindTo: "SendToVisaMenuItemCaption"},
					"Click": {bindTo: "sendToVisa"},
					"Enabled": {bindTo: "isSingleSelected"}
				}));
				return actionMenuItems;
			},
// продолжение модуля....

Спасибо нашёл их. Только как заменить DocumentSectionV2. Он находится в папке Document и при попытке сохранения выдаёт вот такую надпись "Для заданного локального пути не указан путь к хранилищу".
Сохранив ваш код в схеме DocumentPageV2 страницу раздела перестал отображать

Добрый день!

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

"Зарицкий Олег Васильевич" написал:

"Пащенко Александр Сергеевич" написал:

Спасибо. Сейчас попробую сделать

Здравствуйте. Создал замещающую схему и добавил указанные коды. Однако, раздел перестал отображаться. Посмотрите пожалуйста может где-то ошибка есть?

define("DocumentSectionV2", ["VisaHelper", "BaseFiltersGenerateModule",	"DocumentSectionGridRowViewModel"],
	function(VisaHelper, BaseFiltersGenerateModule) {
		return {
			entitySchemaName: "Document",
			methods: {
				/**
				 * Устанавливает значение идентификатора контекстной справки для раздела "Документы"
				 * @overridden
				 */
				initContextHelp: function() {
					this.set("ContextHelpId", 1005);
					this.callParent(arguments);
				},
			attributes: {
                        /**
                         * Заголовок пункта меню "Отправить на визирование"
                         */
                        SendToVisaMenuItemCaption: {
                                dataValueType: Terrasoft.DataValueType.TEXT,
                                value: VisaHelper.resources.localizableStrings.SendToVisaCaption
                        }
                },
                methods: {
                        
                        /**
                         * Действие "Отправить на визирование"
                         */
                        sendToVisa: VisaHelper.SendToVisaMethod,

                        /**
                         * Возвращает коллекцию действий раздела в режиме отображения реестра
                         * @protected
                         * @overridden
                         * @return {Terrasoft.BaseViewModelCollection} Возвращает коллекцию действий раздела в режиме
                         * отображения реестра
                         */
                        getSectionActions: function() {
                                var actionMenuItems = this.callParent(arguments);
                                actionMenuItems.addItem(this.getActionsMenuItem({
                                        Type: "Terrasoft.MenuSeparator",
                                        Caption: ""
                                }));
                                actionMenuItems.addItem(this.getActionsMenuItem({
                                        "Caption": {bindTo: "SendToVisaMenuItemCaption"},
                                        "Click": {bindTo: "sendToVisa"},
                                        "Enabled": {bindTo: "isSingleSelected"}
                                }));
                                return actionMenuItems;
                        },

				/**
				 * @overridden
				 * @inheritDoc BaseSectionV2#initFixedFiltersConfig
				 */
				initFixedFiltersConfig: function() {
					var fixedFilterConfig = {
						entitySchema: this.entitySchema,
						filters: [
							{
								name: "PeriodFilter",
								caption: this.get("Resources.Strings.PeriodFilterCaption"),
								dataValueType: Terrasoft.DataValueType.DATE,
								columnName: "Date",
								startDate: {},
								dueDate: {}
							},
							{
								name: "Owner",
								caption: this.get("Resources.Strings.OwnerFilterCaption"),
								dataValueType: Terrasoft.DataValueType.LOOKUP,
								filter: BaseFiltersGenerateModule.OwnerFilter,
								columnName: "Owner"
							}
						]
					};
					this.set("FixedFilterConfig", fixedFilterConfig);
				},

				/**
				 * @overridden
				 */
				getGridRowViewModelClassName: function() {
					return "Terrasoft.DocumentSectionGridRowViewModel";
				},

				/**
				 * overridden
				 */
				getReportFilters: function() {
					var filters = this.getFilters();
					var recordId = this.get("ActiveRow");
					if (recordId) {
						filters.clear();
						filters.name = "primaryColumnFilter";
						filters.logicalComparisonTypes = Terrasoft.LogicalOperatorType.AND;
						var filter = this.Terrasoft.createColumnInFilterWithParameters(
							this.entitySchema.primaryColumnName, [recordId]);
						filters.addItem(filter);
					}
					return filters;
				},

				/**
				 * overridden
				 */
				prepareResponseCollection: function(collection) {
					this.callParent(arguments);
					var cardPrintMenuItems = this.get("CardPrintMenuItems");
					collection.each(function(item) {
						item.set("CardPrintMenuItems", cardPrintMenuItems);
					}, this);
				}
			},
			diff: /**SCHEMA_DIFF*/[
				{
					"operation": "insert",
					"name": "DataGridActiveRowPrintAction",
					"parentName": "DataGrid",
					"propertyName": "activeRowActions",
					"values": {
						"className": "Terrasoft.Button",
						"style": Terrasoft.controls.ButtonEnums.style.GREY,
						"caption": {"bindTo": "Resources.Strings.PrintRecordGridRowButtonCaption"},
						"tag": "print",
						"visible": {
							bindTo: "getDataGridActiveRowPrintActionVisible"
						}
					}
				}
			]/**SCHEMA_DIFF*/
		};
	});

У Вас лишняя точка с запятой в предпоследней строке и не хватает одной закрывающей фигурной скобки.
Должно быть так:

//весь ваш код
   ]/**SCHEMA_DIFF*/
                }
            }
        });

"Пащенко Александр Сергеевич" написал:
<

Александр, здравствуйте. Посмотрите пожалуйста вот этот код. Записал отдельную схему представления раздела, с родительским объектом "Раздел контакты". Но и там кнопка визирования не отображается. Скорее всего что-то делаю не так. Буду весьма благодарен за помощь

define("ContactSectionV2", ["VisaHelper", "css!VisaHelper"], function(VisaHelper) {
	return {
		entitySchemaName: "Contact",
		attributes: {
                        /**
                         * Заголовок пункта меню "Отправить на визирование"
                         */
			SendToVisaMenuItemCaption: {
				dataValueType: Terrasoft.DataValueType.TEXT,
				value: VisaHelper.resources.localizableStrings.SendToVisaCaption
			}
		},
		methods: {
                       
                        /**
                         * Действие "Отправить на визирование"
                         */
			sendToVisa: VisaHelper.SendToVisaMethod,

                        /**
                         * Возвращает коллекцию действий раздела в режиме отображения реестра
                         * @protected
                         * @overridden
                         * @return {Terrasoft.BaseViewModelCollection} Возвращает коллекцию действий раздела в режиме
                         * отображения реестра
                         */
			getSectionActions: function() {
				var actionMenuItems = this.callParent(arguments);
				actionMenuItems.addItem(this.getActionsMenuItem({
					Type: "Terrasoft.MenuSeparator",
					Caption: ""
				}));
				actionMenuItems.addItem(this.getActionsMenuItem({
					"Caption": {bindTo: "SendToVisaMenuItemCaption"},
					"Click": {bindTo: "sendToVisa"},
					"Enabled": {bindTo: "isSingleSelected"}
				}));
				return actionMenuItems;
			}
			}
	};

Дмитрий, вы создали замещающий клиентский модуль или новую схему представления раздела, с родителем "Раздел контакты"?
Вам нужен именно замещающий клиентский модуль

"Пащенко Александр Сергеевич" написал:

Дмитрий, вы создали замещающий клиентский модуль или новую схему представления раздела, с родительским объектом "Раздел контакты"?

Вам нужен именно замещающий клиентский модуль


Да я просто создал новую схему представления раздела. При замещающей схеме нужно копировать всю родительскую схему + дописывать свои доработки?

Всю схему копировать не нужно. Только объявление модуля и новый/измененный функционал.
В Вашем случаем можно полностью вставить код из предыдущего сообщения. Он будет корректен.

"Ануфриев Дмитрий Юрьевич" написал:

Да я просто создал новую схему представления раздела. При замещающей схеме нужно копировать всю родительскую схему + дописывать свои доработки?

Нет, необходимо указать только следующий обязательный код:
1) Для страницы редактирования:

define('ContactPageV2', ['ContactPageV2Resources', 'GeneralDetails'],
function(resources, GeneralDetails) {
	return {
		entitySchemaName: 'Contact',
		details: /**SCHEMA_DETAILS*/{}/**SCHEMA_DETAILS*/,
		diff: /**SCHEMA_DIFF*/[]/**SCHEMA_DIFF*/,
		attributes: {},
		methods: {},
		rules: {},
		userCode: {}
	};
});

2) Для страницы раздела:

define("ContactSectionV2", ["GridUtilitiesV2", "GoogleIntegrationUtilities", "RightUtilities",
		"ConfigurationConstants", "GoogleIntegrationUtilitiesV2"],
	function(gridUtilitiesV2, GoogleUtilities, RightUtilities, ConfigurationConstants) {
		return {
			entitySchemaName: "Contact",
			attributes: {},
			messages: {},
			mixins: {},
			methods: {}
		};
	});

"Демьяник Алексей" написал:Нет, необходимо указать только следующий обязательный код:

Возможно, поможете. Добавила все коды выше, но при нажатии на кнопку "Отправить на визирование" возникает ошибка (на скриншоте)

Анастасия,
Трудно определить причину по скриншоту. Напишите письмо в тех.поддержку с детальным описанием.

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