Добрый день,

 

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

"Для выполнения разных изменений в разных записях используйте несколько элементов [ Изменить данные ]. - таких уникальных записей будет 20-30 + со временем могут добавляться новые, прописывать вручную параметры каждой не вариант.

Нравится

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

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

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

 

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

 

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

Алексей Следь,

Добрый день,

 

У меня есть реестр записей с уникальными параметрами, например, год-клиент-юр.лицо. И по таймеру хочу идти в другой раздел считать функцию сумма по всем записям с совпадающей связкой год-клиент-юр.лицо, а затем результат функции передавать в реестр в отдельное поле.

Екатерина Пильгук,

ну так все просто. вот этот реестр с уникальными записями есть коллекция записей. Делаете бизнес процесс стартующий по таймеру. Отбираете коллекцию записей год-клиент-юр.лицо - id. Вызываете подпроцесс с параметрами год-клиент-юр.лицо-id. в подпроцессе 2 элемента. Читать данные с параметрами режим чтения Считать функцию. потом изменить данные, где данные отбираете запись по id и пишите результат функции из читать данные.

Алексей Следь,

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

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

Добрый день,

Мне необходимо ограничить пользователю права доступа: может редактировать в записях раздела только одно поле.  В голову приходит только костыльный вариант - дать право доступа Редактирование на данную колонку в доступах на объекты, а по всем остальным колонкам (а их очень много) Чтение. Но тут есть риск покалечить права доступа других пользователей, а их задевать нельзя.

Может, предусмотрен какой-то более удобный способ? 

Нравится

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

Добрый день! Вы имеете ввиду редактировать поле на странице? Через бизнес-правила вроде так можно это сделать.

 

Дмитрий,
Через бизнес-правило "if текущий пользователь = справочник.Пользователь then поле редактируемое"  права на другие колонки же не ограничатся. Плюс, я так понимаю, это правило не позволит другим пользователям редактировать это поле, т.к. будет проходить проверка на текущего пользователя.
Нужно наложить ограничение только на одного п-ля, не затронув остальных.

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

Дмитрий,

 

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

Если ставить правила на запрет изменения всех остальных полей через "пользователь!=" , то помимо того, что их будет порядка 30-40, и некоторые из них работать не будут (т.к. creatio воспринимает только 1 правило, завязанное на 1 поле, а другие игнорирует), но ещё такие правила перетрут права доступа, настроенные через Доступ на объекты. =(

Добрый день, 

 

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

 

Из неочевидного, руководители роли "Может редактировать одну колонку" также унаследуют эти права. 

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

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

Можно ли как то применить фильтр к детали с задержкой, если да то как?

Нравится

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

Делаете сбор коллекции в инит 
получаете айди записи с помощью 
recordId = this.get("PrimaryColumnValue");
радуетесь

Показать все комментарии
attributes: {
            //коллекция записей объектов, используется для фильтров на детали объекты
            "collection": {
                "dataValueType": this.Terrasoft.DataValueType.COLLECTION,
                "type": this.Terrasoft.ViewModelColumnType.VIRTUAL_COLUMN,
                "value": []
            },
"qrtSchema20721e4bDetail473909b0": {
				"schemaName": "qrtSchema20721e4bDetail",
				"entitySchemaName": "qrtObject",
				"filterMethod": "setObjectFilers"
			}
onEntityInitialized: function(){
				this.callParent(arguments);
                this.console.log("onEntityInitialized");
				this.getProjectCollections();
			},
 setObjectFilers: function(){
                debugger;
                var DEFAULT = "00000000-0000-0000-0000-000000000000";
                this.console.log("setObjectFilers");
                var collection = this.get("collection");
                this.console.log("Массив: "+collection);
                var filterGroup = Ext.create("Terrasoft.FilterGroup");
 
 
                if(collection.length !== 0){
                    filterGroup.add("IdFilter",Terrasoft.createColumnInFilterWithParameters("Id", collection));
                } else {
                    filterGroup.add("IdFilter",
                                    Terrasoft.createColumnFilterWithParameter(
                                        Terrasoft.ComparisonType.EQUAL, "Id", DEFAULT));
                }
 
 
 
                return filterGroup;
 
            },
            /**
             * получает коллекцию объектов по лидам и продажам
             */
            getProjectCollections:function(){
                var mas = [];
                Terrasoft.chain(
                    function(next){
                        var esq = Ext.create("Terrasoft.EntitySchemaQuery", {
                            rootSchemaName: "Opportunity"
                        });
                        this.console.log("obj");
                        esq.addColumn("qrtObject.Id");
                        // Создание экземпляра первого фильтра.
                        var esqFirstFilter = esq.createColumnFilterWithParameter(Terrasoft.ComparisonType.EQUAL, "qrtProject", this.get("Id"));
                        esq.filters.add("esqFirstFilter", esqFirstFilter);
 
                        esq.getEntityCollection(function (result) {
                            if (result.success) {
                                result.collection.each(function (item) {
                                    this.console.log(item.get("qrtObject.Id"));
                                    mas.push(item.get("qrtObject.Id"));
 
                                });
                            }
                            next();
                        }, this);
                    }, 
                    function(next){
                        this.console.log(mas);
                        self.set("collection", mas);
                        this.updateDetail({detail: "qrtSchema20721e4bDetail473909b0", realoadAll: true});
                        this.setObjectFilers();
 
                    }, this
                )           
            }

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

Нравится

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

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

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

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

Нравится

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

Объект не нашел, но сделал удаление без связанных с помощью метода 
 

GridUtilitiesService deleteRecordsService = new GridUtilitiesService();
//первый параметр айдишники записей, а второй целевой объект
deleteRecordsService.DeleteRecords(new string[]{"ac52a8ab-f404-4809-b590-e4beeec2eacc","f9f8c61d-64b3-4686-862f-e261150e7fca","320cc71e-e053-4eb2-b6eb-8ca96728bb51"}, "Activity");

 

Объект не нашел, но сделал удаление без связанных с помощью метода 
 

GridUtilitiesService deleteRecordsService = new GridUtilitiesService();
//первый параметр айдишники записей, а второй целевой объект
deleteRecordsService.DeleteRecords(new string[]{"ac52a8ab-f404-4809-b590-e4beeec2eacc","f9f8c61d-64b3-4686-862f-e261150e7fca","320cc71e-e053-4eb2-b6eb-8ca96728bb51"}, "Activity");

 

Добрый день!

 

Найти идентификатор экземпляра процесса, в котором используется удаляемая запись можно запросом:
select SysProcessId from SysProcessElementData ed join SysEntityCommonPrcEl ede on ede.ProcessElementId = ed.Id where ede.RecordId = 'id удаляемой записи'

Найденный экземпляр необходимо найти в системе и отменить выполнение.

Рекомендую обратить внимание на метод DeleteWithCancelProcess в классе Entity, с помощью которого в задание сценарии можно удалить связь и отменить процесс. 

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

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

Нельзя удалить или отредактировать данные пакета

Я на локальной среде залил пакет 
разблокировал его, как обычно делаю
update SysPackage
set IsChanged = 1, InstallType = 0, IsLocked = 1, Maintainer = 'Quarta'
where Name in ('qrtAbipaCargoBase')
 в списке пакетов он показан как доступный для редактирования
в sql тоже показано что колонки . которые обновляли изменились на нужное состояние
 

Нравится

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

Для разблокировки пакета есть только два требования:

1) Совпадение издателя в системной настройки с колонкой "Maintainer" в таблице "SysPackage" (в записи необходимого пакета)

2) Значение колонки "InstallType" = 1 (или true для PostgreSQL)

Для разблокировки пакета есть только два требования:

1) Совпадение издателя в системной настройки с колонкой "Maintainer" в таблице "SysPackage" (в записи необходимого пакета)

2) Значение колонки "InstallType" = 1 (или true для PostgreSQL)

Александр Тыра,
у меня все нормально апдейтнулось я же говорю 
но при этом пакет как-будто заблочен

Александр Тыра,

1) Совпадение издателя в системной настройки с колонкой "Maintainer" в таблице "SysPackage" (в записи необходимого пакета)
да я указывал издателя пакета, а не издателя из сис настройки

 

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

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

Нравится

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

Если "копнуть" и посмотреть, как работает ShowBodyMask, то можно увидеть, что маска применяется к элементу, переданному в конфиге. Если таковой не указан, то к body. Потому для решения Вашей задачи достаточно примерно такой конструкции:

this.showBodyMask({
	selector: "#MiniPageContentContainer"
});

 

Добрый день, Александр!

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

ч 

Жмурко Сергей Николаевич,

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

Если "копнуть" и посмотреть, как работает ShowBodyMask, то можно увидеть, что маска применяется к элементу, переданному в конфиге. Если таковой не указан, то к body. Потому для решения Вашей задачи достаточно примерно такой конструкции:

this.showBodyMask({
	selector: "#MiniPageContentContainer"
});

 

Если нужно заблокировать и кнопки, то id будет уже AlignableMiniPageContainer

Лопатин Константин,

спасибо большое. В принципе так и пробовал, но упустил что нежно еще слово "Container"

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

При запросе с локальной машины иp терасофт к внешнему api 
выдает ошибку
При это если отправлять такой же запрос не из системы то все проходит нормально
Невозможно разрешить удаленное имя:
ошибка настолько абстрактная , что я не знаю куда копать, сейчас все подозрения на протоколы безопасности

запрос я делаю следующим кодом 
 

public string GetJson(string URL)
    {
      try
      {
         ServicePointManager.SecurityProtocol |=
                SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12;
        var request = (HttpWebRequest)WebRequest.Create(URL);
        request.Credentials = CredentialCache.DefaultCredentials;
        WebResponse webResponse = request.GetResponse();
        Stream webStream = webResponse.GetResponseStream();
        StreamReader responseReader = new StreamReader(webStream);
        string response = responseReader.ReadToEnd();
        return response;
      }
      catch (WebException e)
      {
        if(e.Response != null){
            return new StreamReader(e.Response.GetResponseStream()).ReadToEnd().ToString();
          }
        return e.Message;
      }
    }

 

Нравится

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

После установки дополнения "Contact connections chart for Creatio" на вкладке "Who knows who" не отображаются данные указанные на детали "Взаимосвязи".

Может кто-то знает в чем может быть причина?

Нравится

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

У вас указано, что система версии 7.17.

С версии 7.17.0 новый же дизайнер взаимосвязей, где кардинально была изменена логика работы и хранения взаимосвязей.

Дата последнего обновления дополнения "Contact connections chart for Creatio": 27.10.2020

Скорее всего дополнение не поддерживает новую структуру взаимосвязей.

Олег,

 

обратите внимание, что это приложение совместимо только с СУБД MS SQL. Скорее всего установили приложение на несовместимый сайт.

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

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

Нравится

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

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

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

 т.е если я редактирую запись и оно заполнено значением  , которое я подставляю . то может возникнут такая ошибка
Т.е к примеру у нас в поле есть контрагент А и я на вебсервисе заполняю код тоже контрагентом А
А обходить это стоит проверкой на соответствие  полей по типу A != A или проверкой на null?

А как быть если ошибка возникает при добавлении записи, т.е это может свидетельстовать о том. что поле при создании уже заполнено по умолчанию?

Не совсем понял, что Вы делаете. При редактировании записи ошибка со внешними ключами может быть, если в справочное поле пишут Id несуществующей в справочнике записи. При добавлении, помимо этого, ошибка, если пытаются вставить две записи с одинаковым Id. Это не зависит, осуществляется ли вставка в клиентской логике, серверной, в БП или по интеграции. В итоге всё равно это всё превращается в SQL-запросы к базе.

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

Чтобы такого не было нужно при создании логики (JS, C#, БП) внимательно следить за такими случаями, и не устанавливать какие-попало значения в колонки.

Так же один из самых частых случаев - это когда пытаются установить пустой идентификатор в значение колонки. Важно помнить, что Guid.Empty и null - это разные вещи. Поэтому перед установко желательно всегда делать проверку на Guid.Empty.

Владислав Литвинчук пишет:
Ошибки со внешними ключами могут быть только в одном случае. В колонку сохраняется Id объекта не того, на который смотрит колонка.

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

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