Доброго утра всем.

Есть проблема. С авторизацией LDAP на .NET Core.

В Академии указано.

Внесите изменения в файл Terrasoft.WebHost.dll.config.

<provider name="Ldap" type="Terrasoft.Authentication.Core.Ldap.NetStandardLdapProvider, Terrasoft.Authentication">
<parameters>
    <add name="ServerPath" value="testldap.com" />
    <add name="DistinguishedName" value="dc=ctl,dc=com" />
    <add name="UseLoginUserLDAPEntryDN" value="false" />
    <add name="SearchPattern" value="(&amp;(sAMAccountName={0})(objectClass=person))" />
    <!--При “Kerberos” аутентификации-->
    <add name="KeyDistributionCenter" value="ctl.com" />
    <!--При использовании LDAPS-->
    <add name="SecureSocketLayer" value="false" />
    <add name="CertificateFileName" value="" />
</parameters></provider>

 

Но в файле Terrasoft.WebHost.dll.config нету этих настроек. 

Причем если я добавляю их стенд не запускается.

Может кто сталкивался с настройками аутентификации c LDAP на Linux.?

Нравится

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

Добрый день!

Проверьте, есть ли в файле Terrasoft.WebHost.dll.config секция:

 <provider name="LdapProvider" type="Terrasoft.Authentication.Core.Ldap.NetStandardLdapProvider, Terrasoft.Authentication">

 

Изменения, описанные в документации, нужно вносить в этот блок.

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

Доброго утра всем.

Есть проблема. С авторизацией LDAP на .NET Core.

В Академии указано.

Внесите изменения в файл Terrasoft.WebHost.dll.config.

<provider name="Ldap" type="Terrasoft.Authentication.Core.Ldap.NetStandardLdapProvider, Terrasoft.Authentication">
<parameters>
    <add name="ServerPath" value="testldap.com" />
    <add name="DistinguishedName" value="dc=ctl,dc=com" />
    <add name="UseLoginUserLDAPEntryDN" value="false" />
    <add name="SearchPattern" value="(&amp;(sAMAccountName={0})(objectClass=person))" />
    <!--При “Kerberos” аутентификации-->
    <add name="KeyDistributionCenter" value="ctl.com" />
    <!--При использовании LDAPS-->
    <add name="SecureSocketLayer" value="false" />
    <add name="CertificateFileName" value="" />
</parameters></provider>

 

Но в файле Terrasoft.WebHost.dll.config нету этих настроек. 

Причем если я добавляю их стенд не запускается.

Может кто сталкивался с настройками аутентификации c LDAP на Linux.?

Нравится

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

Добрый день.

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

Нравится

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

Андрей, это скорее всего произошло из-за того, что тот пользователь который настраивал интеграцию с LDAP автоматически стал "Ответственным" за БП "Синхронизировать данные о пользователях с LDAP"(Так как был в орг.роли "System administrators" ). И так как его учетная запись стала неактивной - то и процесс соответственно.

 

Вам необходимо войти в систему под пользователем у которого организационная роль "System administrators" , перейти в настройки LDAP и достаточно будет повторно ввести "Логин администратора" и "Пароль" от сервера. Учтите что если сервер Creatio установлен на Linux, то используйте формат “domain\login“. И сохранить настройки.

Андрей, это скорее всего произошло из-за того, что тот пользователь который настраивал интеграцию с LDAP автоматически стал "Ответственным" за БП "Синхронизировать данные о пользователях с LDAP"(Так как был в орг.роли "System administrators" ). И так как его учетная запись стала неактивной - то и процесс соответственно.

 

Вам необходимо войти в систему под пользователем у которого организационная роль "System administrators" , перейти в настройки LDAP и достаточно будет повторно ввести "Логин администратора" и "Пароль" от сервера. Учтите что если сервер Creatio установлен на Linux, то используйте формат “domain\login“. И сохранить настройки.

Kurylo Pavel, Спасибо, сработало

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

Здравствуйте, помогите решить конфликт. После updatePackedgeFromRepository на продакшине вижу конфликты ресурсов, там же нет разработки, поетому не понимаю, как ети конфликты решить, правой кнопкой мыши решить не вийдет, возможно у вас есть решение. Спасибо 

Нравится

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

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

Литвинко Павел, каким образом я могу их решить локально, может знаете? если откріть ети ресурсы локально и на проде (в папке темп iis), то вижу что они одинаковые по контексту

Nataliia, добрый день!
Попробуйте перераздать права Full Сontrol для пользователя под которым запущен IIS.
Также, проверьте, существуют ли эти файлы по пути указанному в ошибках.

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

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

 

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

 

Пробую прописать вот так (прилагаю), но фильтр не срабатывает. Скорее всего я не правильно пытаюсь узнать, к какому департаменту относится текущий пользователь, посредством EntitySchemaQuery. Информация о департаменте содержится в объекте Contact.

 

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

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

 

 

Прикрепленные файлы

Нравится

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

Там идет асинхронный запуск, потому Ваш "return" не попадает в него. Вам необходимо сделать Join в колонке по которой делаете фильтр. Если напишите какие колонки в объекте этого раздела, то могу помочь верно сделать фильтр

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

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

Мне нужно при удалении элемента детали проверять последняя это строка или нет. Я в событии Deleting проверяю и если строка последняя, то бросаю эксепшен:   

throw new Exception("У СОба единственный застройщик. Его нельзя удалять. Перед удалением добавьте другого!");

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

Нравится

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

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

Пример отправки сообщения есть в исходном коде BaseVisa из пакета NUI, метод PublishClientVisaInfo. Пример обработки есть в клиентской схеме MLModelPage, функция subscribeServerChannelEvents.

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

Пример отправки сообщения есть в исходном коде BaseVisa из пакета NUI, метод PublishClientVisaInfo. Пример обработки есть в клиентской схеме MLModelPage, функция subscribeServerChannelEvents.

Кто-то нашел работающий способ, чтобы кинуть "свое" сообщение в случае отмены удаления?

потому что мы не нашли.

 

  • если кидать ексепшн, то удаление не происходит, но выводится базовое окно "невозможно удалить" с пустым "подробнее".
  • если пробрасывать сообщение и возвращать фалсе, то все равно обьект удаляется (но сообщение ловится)
  • если пробрасывать сообщение и кидать ексепшн, то базовое окно "невозможно удалить" перекрывает наше сообщение (сообщение-то есть, только его можна обнаружить, если отлаживаться и идти пошагово, тогда оно "успевает" показаться)

 

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

 

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

 

для справки, может, кому-то пригодится (да и себе на потомsmiley ). 

"проброска" сообщения с сервера на клиент:

 

1) в скрипте БП или сервисе пишется строчка:

Terrasoft.Configuration.MsgChannelUtilities.PostMessage(UserConnection, "CannotDeleteFromTeamDetail", "CannotDeleteFromTeamDetail");

не забыть подключить скрипт Terrasoft.Configuration;

2) ищем скрипт ClientMessageBridge . если он есть в пользовательском пакете, то дописываем свое сообщение, если нету, наследуем от базового и пишем свое сообщение.
скрипт выглядит так (с одним нашим сообщением):

define("ClientMessageBridge", ["ConfigurationConstants"],
    function(ConfigurationConstants) {
        return {
            messages: {
                "CannotDeleteFromTeamDetail": {
                    "mode": Terrasoft.MessageMode.BROADCAST,
                    "direction": Terrasoft.MessageDirectionType.PUBLISH
                }
            },
            methods: {
                init: function() {
                    this.callParent(arguments);
                    this.addMessageConfig({
                        sender: "CannotDeleteFromTeamDetail",
                        messageName: "CannotDeleteFromTeamDetail"
                    });
           
                }
            }
        };
    });

3) в клиенте, где нужно "поймать" сообщение подписываемся на него (у нас было в методе init детали):
блок месседж

messages: {
            "CannotDeleteFromTeamDetail": {
                mode: Terrasoft.MessageMode.BROADCAST,
                direction: Terrasoft.MessageDirectionType.SUBSCRIBE
            }
        }

метод инит

init: function() {
        this.callParent(arguments);
        
        this.sandbox.subscribe("CannotDeleteFromTeamDetail", function(args){
            Terrasoft.showInformation("Невозможно удалить, т.к. для этого контакта есть записи Активностей в периоде!");
        }, this);
    }

   
Замена базового метода меню детали "удалить" на свое:
1) в блок методов добавляем функцию:

getDeleteRecordMenuItem: function() {
                return this.getButtonMenuItem({
                    Caption: {"bindTo": "Resources.Strings.RemoveFromTeamMenuCaption"},//можно переименовать или оставить базовое название Удалить
                    Click: {"bindTo": "removeFromTeamRecords"},//вызов своего метода
                    Enabled: {bindTo: "isAnySelected"},
                    Visible: {bindTo: "IsEnabled"}
                });
            },

2) свой метод removeFromTeamRecords -- по сути, часть базового (с проверками на выборку в реестре) с заменой вызовов базового метода удаления на свой checkCanRemoveFromTeamRecordsAndDelete, в котором сначала выполнить проверку условия (можно ли удалять), и если можно -- вызывать базовый метод deleteRecords()

removeFromTeamRecords: function() {
                const activeRow = this.getActiveRow();
                if (activeRow &amp;&amp; activeRow.isNew) {
                    this.checkCanRemoveFromTeamRecordsAndDelete([activeRow.get("Id")], this);
                } else {
                    const items = this.getSelectedItems();
                    if (!items || !items.length) {
                        return;
                    }
                    this.checkCanRemoveFromTeamRecordsAndDelete(items, this);
                }
            },
checkCanRemoveFromTeamRecordsAndDelete: function(items, scope){
                var msgOneContact = "Невозможно удалить, т.к. для этого Контакта есть записи Активностей в периоде!";
                var msgManyContacts = "Невозможно удалить, т.к. среди Контактов есть Контакты с записями Активностей в периоде!";
                
                var config = {
                    serviceName: "MyService",
                    methodName: "CanDeleteContactFromTeam",
                    callback: function(response) {
                        var result = response.CanDeleteContactFromTeamResult;
                        this.canDelete = result;
                        if (!!result){
                            scope.deleteRecords();
                        } else {
                            Terrasoft.showInformation((items.length == 1) ? msgOneContact : msgManyContacts);
                        }
                    },
                    data: {
                        TeamIds: items
                    },
                    scope: scope,
                    timeout: 10000
                };
                serviceHelper.callService(config);    
            }

            
условие проверки выполнено через вызов веб-сервиса на сервере, код приводить уже не буду, есть примеры и почитать можно здесь и/или здесь.
также не забыть прописать в связи страницы serviceHelper (для нашего случая, т.к. используем вызов веб-сервиса)

define("MyDetail", ["ServiceHelper"],   function(serviceHelper) {

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

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

Коллеги, прошу Вашей помощи!

Есть задача: При отработки определенного типа активности и переводе её в состояние "Завершена", должна происходить проверка, добавлен ли в файлы и ссылки этой активности хотя бы один документ. Если добавлен, то сохранять активность, если нет - то выводить предупреждающее сообщение. 

 

Я попробовал в конфигурации страницы активности ActivityPageV2 переопределить метод save() и прописать там проверку на вложенный документ таким образом: 

 

save: function() {

    var activityStatus = (this.get("Status").value).toString();
    
    var activityTitle = (this.get("Title")).toString();
    
    if (activityTitle === "Активность для Управления оценки рисков")
    {
        if (activityStatus === "4bdbb88f-58e6-df11-971b-001d60e938c6") {
            
            var activityId = this.get("Id");    
            
            var checkInfo = false;
            
            var esq = Ext.create("Terrasoft.EntitySchemaQuery", {
                rootSchemaName: "ActivityFile"
            });
            
            esq.addColumn("Name","actName");
            
            var esqFirstFilter = esq.createColumnFilterWithParameter(Terrasoft.ComparisonType.EQUAL, "Activity", activityId);
            
            esq.filters.add("esqFirstFilter", esqFirstFilter);
            
            esq.getEntityCollection(function(result) {
                if (result.success) {
                    
                    checkInfo = true;
                    
                }
            }, this);
            
            if (checkInfo) {
                this.callParent(arguments); //если документ есть сохраняем страницу
            } else {
                this.showInformationDialog(Ошибка. Не добавлен документ в файлы и ссылки!); //если документа нет - выводим сообщение
            }
            
        }
        else {
            this.callParent(arguments);
        }
        
    }
    else
    {
        this.callParent(arguments);
    }                                   
}

 

После долгих проверок выяснилось, что  параметр checkInfo не передает измененное значение с false на true внутри esq.getEntityCollection(function(result) {},this) и остается в значении false, хотя проверка в ActivityFile отрабатывает корректно. 

Вопрос: как передать измененное значение checkInfo из esq.getEntityCollection обратно на страницу, чтобы далее можно было прописывать различные условия проверки? Или может я вообще не правильно осуществляю проверку вложенного документа и есть другие способы?

Нравится

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

Вот один из примеров, как это можно реализовать:

 

 define("ActivityPageV2", [],
	function() {
		return {
			entitySchemaName: "Activity",
			attributes:{
				"isSecond": {
					"dataValueType": Terrasoft.DataValueType.BOOLEAN,
					"type": Terrasoft.ViewModelColumnType.VIRTUAL_COLUMN,
					"value": false
				}
			},
			methods: { 
				save: function() {
 
					if(this.get("isSecond")){
						this.callParent(arguments);
						this.set("isSecond", false);
					}else{
						var activityStatus = (this.get("Status").value).toString();
 
						var activityTitle = (this.get("Title")).toString();
 
						if (activityTitle === "Активность для Управления оценки рисков")
						{
							if (activityStatus === "4bdbb88f-58e6-df11-971b-001d60e938c6") {
 
								var activityId = this.get("Id");    
 
								var checkInfo = false;
 
								var esq = Ext.create("Terrasoft.EntitySchemaQuery", {
									rootSchemaName: "ActivityFile"
								});
 
								esq.addColumn("Name","actName");
 
								var esqFirstFilter = esq.createColumnFilterWithParameter(Terrasoft.ComparisonType.EQUAL, "Activity", activityId);
 
								esq.filters.add("esqFirstFilter", esqFirstFilter);
 
								esq.getEntityCollection(function(result) {
 
									if (result.success &amp;&amp; result.collection.collection.length &gt; 0) {
										this.set("isSecond", true);
										this.save();//если документ есть сохраняем страницу
									} else {
										this.showInformationDialog("Ошибка. Не добавлен документ в файлы и ссылки!"); //если документа нет - выводим сообщение
									}
 
								}, this);
 
							}
							else {
								this.callParent(arguments);
							}
 
						}
						else
						{
							this.callParent(arguments);
						}  
					}
				}, 
				test: function(){
 
				}
			},
			diff: /**SCHEMA_DIFF*/[
			]/**SCHEMA_DIFF*/
		};
	});

 

Вот один из примеров, как это можно реализовать:

 

 define("ActivityPageV2", [],
	function() {
		return {
			entitySchemaName: "Activity",
			attributes:{
				"isSecond": {
					"dataValueType": Terrasoft.DataValueType.BOOLEAN,
					"type": Terrasoft.ViewModelColumnType.VIRTUAL_COLUMN,
					"value": false
				}
			},
			methods: { 
				save: function() {
 
					if(this.get("isSecond")){
						this.callParent(arguments);
						this.set("isSecond", false);
					}else{
						var activityStatus = (this.get("Status").value).toString();
 
						var activityTitle = (this.get("Title")).toString();
 
						if (activityTitle === "Активность для Управления оценки рисков")
						{
							if (activityStatus === "4bdbb88f-58e6-df11-971b-001d60e938c6") {
 
								var activityId = this.get("Id");    
 
								var checkInfo = false;
 
								var esq = Ext.create("Terrasoft.EntitySchemaQuery", {
									rootSchemaName: "ActivityFile"
								});
 
								esq.addColumn("Name","actName");
 
								var esqFirstFilter = esq.createColumnFilterWithParameter(Terrasoft.ComparisonType.EQUAL, "Activity", activityId);
 
								esq.filters.add("esqFirstFilter", esqFirstFilter);
 
								esq.getEntityCollection(function(result) {
 
									if (result.success &amp;&amp; result.collection.collection.length &gt; 0) {
										this.set("isSecond", true);
										this.save();//если документ есть сохраняем страницу
									} else {
										this.showInformationDialog("Ошибка. Не добавлен документ в файлы и ссылки!"); //если документа нет - выводим сообщение
									}
 
								}, this);
 
							}
							else {
								this.callParent(arguments);
							}
 
						}
						else
						{
							this.callParent(arguments);
						}  
					}
				}, 
				test: function(){
 
				}
			},
			diff: /**SCHEMA_DIFF*/[
			]/**SCHEMA_DIFF*/
		};
	});

 

Mykhailo Storozhuk,

Супер! Спасибо большое!!! А то 3 дня мучался, пытаясь найти решение)) Тоже через атрибут пробовал, но не додумался перевызывать метод save() c проверкой этого атрибута. Благодарю!

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

Есть JSON на 35 000+ строк.
На стороне сервера запрос принимается и обрабатывается 118 – 124 секунды.

Во время обработки запроса к нам приходит ошибка:

Received an unexpected EOF or 0 bytes from the transport stream. Trace at System.Net.ConnectStream.Read(Byte[] buffer, Int32 offset, Int32 size) at System.IO.StreamReader.ReadBuffer() at System.IO.StreamReader.ReadToEnd() at Terrasoft.Configuration.UsrCustomNamespace.UsrHelperForAuction.SendRequest[T](String api, T requestObject, Guid auctionId)

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

В CRM при отправке запроса, HTTP Request был добавлен таймаут = 600 * 1000.

Ошибка осталась та же.

Нравится

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

Добрый день.

Подскажите, сколько по времени занимает выполнение запроса в Postman?
Если у вас закрывается сессия до выполнения запроса, я бы рекомендовал обратить внимание на системную настройку UserSessionTimeout. Максимальное значение данной настройки - 720 мин.

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

Добрый день!

Подскажите, по какой причине не отображается раздел [Обращения] в рабочем месте?

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

Нравится

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

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

Здесь стоит проверять сразу несколько нюансов:

- проверьте что объект не имеет ошибок публикации, скомпилируйте приложение. 

- проверьте права, на раздел/рабочее место, а также что пользователь обладает нужной лицензией.

- проверьте привязку в таблице SysModul. Может быть такое, что раздел был добавлен в одно рабочее место два раза и на уровне базы данных образовались дубли, в таком случае раздел просто не отобразиться. Нужно удалить записи на уровне БД и добавить раздел снова.

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

 

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

Добрый день!

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

Нравится

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

Лариса, если это дополнение Kanban view for Creatio, то лучше будет уточнить у его авторов по ссылке. Из общих соображений, проверьте, все ли у него есть права на записи этого раздела, где Вы строите канбан, и нет ли при переходе в этот режим в консоли браузера ошибок, которые могут сказать больше о причине.

 

Не уверен, что это Ваш случай, но было похожее, только после обновления на 7.12.3, 7.12.4: не открываются разделы и не подгружаются гриды в разделах. 

Ошибка возникает из-за того что в замещающих схемах BaseSectionV2 вызывается CloseCard, в котором обращется к this.$SelectedRows.length, но инициализация $SelectedRows происходит позже. 
Ошибка решается изменением метода: 

    closeCard: function() {
                this.hideCard();
                this.removeCardHistoryState();
                this.updateCardHeader();
                const isMultiSelectMode = this.$MultiSelect &amp;&amp; this.$SelectAllMode;
                const isNotSelected = !isMultiSelectMode &amp;&amp; this.$SelectedRows &amp;&amp; this.$SelectedRows.length === 0;
                if (isNotSelected) {
                    this.switchActiveRowActions();
                }
                this.reloadGridColumnsConfig(true);
                this.ensureActiveRowVisible();
            }

 

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

спасибо за ответ! наверное, если бы ошибка возникла из-за обновления, то тогда пропало бы отображание у всех, а здесь только у некоторых

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

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

К сожалению, не помогло

Лариса, тогда лучше связаться с авторами дополнения, описать им вопрос подробнее.

Лариса Михайлова, подскажите, удалось решить проблему?

Добрый день, Ольга!

Если у вас возникли трудности в использованием приложения Kanban view for Creatio, рекомендуем обратиться к разработчику. Решение поддерживается через ответы на GitHub: https://github.com/Advance-Technologies-Foundation

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