исходный_код_объектов_при_редактировании_в_7.
Технические вопросы
7.x

Не показывается исходный код объектов при редактировании в BPMOnline 7.

Нравится

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

Сергей, скорее всего, проблема с Silverlight. Проверить можно на диаграммах процесса (не будут отображаться, если Silverlight работает некорректно).
Проблема локальная или воспроизводится и на других машинах?

Всем спасибо, проблема была в настройках IIS (настройки аутентификации).

Показать все комментарии
Фильтрация в скрипте Версия 5.1.1.157
Технические вопросы
5.x

Как сделать фильтрацию или в следующим примере:

использовал

{"logicalOperation", LogicalOperationStrict.Or}
не работает

filters.Add(new Dictionarystring, object> {
                                       {"comparisonType", FilterComparisonType.IsNotNull},
                                       {"leftExpressionColumnPath", "Debt.Id"},
                                       {"useDisplayValue", false},
                                                                   {"rightExpressionParameterValues", new object[] {Guid.Empty}}
                                                                   
                                                                }
                                                        );
                                filters.Add(new Dictionarystring, object> {
                                       {"comparisonType", FilterComparisonType.IsNotNull},
                                       {"leftExpressionColumnPath", "ReceivDebt.Id"},
                                       {"useDisplayValue", false},
                                                                   {"rightExpressionParameterValues", new object[] {Guid.Empty}}
                                                                 
                                                                }
                                                        );

Нравится

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

Здравствуйте, Баглан!
А работает, если применять только один фильтр?

"Андрей Каспаревич" написал:filters.Add(new Dictionary {
                                       {"comparisonType", FilterComparisonType.IsNotNull},
                                       {"leftExpressionColumnPath", "Debt.Id"},
                                       {"useDisplayValue", false},
                                                                   {"rightExpressionParameterValues", new object[] {Guid.Empty}}
                                                                   
                                                                }
                                                        );

Если применять 1 фильтр работает
к примеру этот:
filters.Add(new Dictionary {
{"comparisonType", FilterComparisonType.IsNotNull},
{"leftExpressionColumnPath", "Debt.Id"},
{"useDisplayValue", false},
{"rightExpressionParameterValues", new object[] {Guid.Empty}}

}
);

Баглан, приведите, пожалуйста, полный код скрипта.
В частности, интересует инициализация filters. Должно быть что-то вроде:

filters = structure.CreateFiltersGroup("CustomFilters", LogicalOperationStrict.Or);

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

Баглан, приведите, пожалуйста, полный код скрипта.

В частности, интересует инициализация filters. Должно быть что-то вроде:

filters = structure.CreateFiltersGroup("CustomFilters", LogicalOperationStrict.Or);

С уважением,

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

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

Андрей добрый день, высылаю полный текст скрипта на C#

Page.CallFromQueueEdit.PrepareLookupFilter += delegate (object sender, LookupEditEventArgs e) {
                Collection<Dictionary<string, object>> filters = e.Filters;
                filters.Add(new Dictionary<string, object> { 
	                               {"comparisonType", FilterComparisonType.Equal}, 
	                               {"leftExpressionColumnPath", "Type.Id"},
	                               {"useDisplayValue", false}, 
	                               {"rightExpressionParameterValues", new object[] {activityTypeId}}
								}
							); 
                filters.Add(new Dictionary<string, object> { 
	                               {"comparisonType", FilterComparisonType.LessOrEqual}, 
	                               {"leftExpressionColumnPath", "StartDate"},
	                               {"useDisplayValue", false}, 
	                               {"rightExpressionParameterValues", new object[] {UserConnection.CurrentUser.GetCurrentDateTime()}}
								}
							); 							
                filters.Add(new Dictionary<string, object> { 
	                               {"comparisonType", FilterComparisonType.Equal}, 
	                               {"leftExpressionColumnPath", "Status.Id"},
	                               {"useDisplayValue", false}, 
	                               {"rightExpressionParameterValues", new object[] {NotStartedStatusId, InWorkStatusId}}
								}
							); 	
                filters.Add(new Dictionary<string, object> { 
	                               {"comparisonType", FilterComparisonType.IsNotNull}, 
	                               {"leftExpressionColumnPath", "Debt.Id"},
	                               {"useDisplayValue", false},
								   {"rightExpressionParameterValues", new object[] {Guid.Empty}},
								   {"logicalOperation", LogicalOperationStrict.Or}
								}
							);
				/*
				filters.Add(new Dictionary<string, object> { 
	                               {"comparisonType", FilterComparisonType.IsNotNull}, 
	                               {"leftExpressionColumnPath", "ReceivDebt.Id"},
	                               {"useDisplayValue", false},
								   {"rightExpressionParameterValues", new object[] {Guid.Empty}},
								   {"logicalOperation", LogicalOperationStrict.Or}
								}
							); */
};

Баглан, судя по коду, проблема в том, что фильтры добавляются по одному, а не блоком. То есть Вам нужно сформировать блок фильтров с логическим оператором и уже его добавлять в e.Filters.
Попробуйте так:

Page.CallFromQueueEdit.PrepareLookupFilter += delegate (object sender, LookupEditEventArgs e) {
                var filters = structure.CreateFiltersGroup("CustomFilters", LogicalOperationStrict.Or); 
                filters.Add( structure.CreateFilterWithParameters( dataSource.Schema, 
                FilterComparisonType.Equal, "Type.Id", activityTypeId)); 
                filters.Add( structure.CreateFilterWithParameters(dataSource.Schema, 
                FilterComparisonType.LessOrEqual, "StartDate",   UserConnection.CurrentUser.GetCurrentDateTime());                                                      
               //....
                e.Filters.Add(filters);

"Андрей Каспаревич" написал:{"comparisonType", FilterComparisonType.IsNotNull},

Ругаеться на это e.Filters.Add(structure); тип не верный не верно передаем параметр structure, должно быть таким образом: Collection>

DataSource dataSource = Page.ActivityDataSource;
				var structure = dataSource.CurrentStructure;
				var filterGroupName = "CustomFilters";
				//remove existing filters
                var filters = dataSource.FindFiltersGroupByName(filterGroupName);
                if (filters != null) {
	                structure.Filters.Remove(filters);
                }
                filters = structure.CreateFiltersGroup(filterGroupName, LogicalOperationStrict.And); 
                filters.Add(structure.CreateFilterWithParameters(dataSource.Schema, FilterComparisonType.Equal, "Type.Id", activityTypeId)); 
                filters.Add(structure.CreateFilterWithParameters(dataSource.Schema, FilterComparisonType.LessOrEqual, "StartDate",   UserConnection.CurrentUser.GetCurrentDateTime()));   
 
				var statusFilters = new DataSourceFilterCollection() {
	                LogicalOperation = LogicalOperationStrict.Or,
                };
				statusFilters.Add(dataSource.CreateFilterWithParameters(FilterComparisonType.Equal, "Status.Id", NotStartedStatusId));
				statusFilters.Add(dataSource.CreateFilterWithParameters(FilterComparisonType.Equal, "Status.Id", InWorkStatusId));
				filters.Add(statusFilters);
 
				var debtFilters = new DataSourceFilterCollection() {
	                LogicalOperation = LogicalOperationStrict.Or,
                };
				debtFilters.Add(dataSource.CreateFilterWithParameters(FilterComparisonType.IsNotNull, "Debt.Id"));
				debtFilters.Add(dataSource.CreateFilterWithParameters(FilterComparisonType.IsNotNull, "ReceivDebt.Id"));
				filters.Add(debtFilters);
				structure.Filters.Add(filters);
				e.Filters.Add(structure);

Здравствуйте, Баглан!
Уточнил информацию у разработчиков.
Особенность фильтрации на PrepareLookupFilter состоит в том, что либо всё фильтруется через оператор “AND” (по умолчанию) либо через оператор “OR” (Логика устанавливается при помощи параметра)

e.ParametersValue.Add("logicalOperation", LogicalOperationStrict.Or);

Так как в примере идет пересечение AND и OR логики фильтрации, то остается более сложный путь:
1) Написать запрос, с помощью которого отберутся только те Id, которые удовлетворяют условию фильтрации;
2) В фильтрации PrepareLookupFilter фильтровать по найденным Id.
Пример реализации второго варианта:

List<object> offeringList = new List<object>();
var offeringSelect = new Select(UserConnection).
                Column("o", "Id").
                From("Offering").As("o").
                InnerJoin("OfferingType").As("ot").
                On("o", "TypeId").IsEqual("ot", "Id"). 
                InnerJoin("Service").As("s").
                On("o", "ServiceId").IsEqual("s", "Id"). 
                InnerJoin("TypeOfService").As("tos").
                On("s", "TypeOfServiceId").IsEqual("tos", "Id").
                Where("ot", "IsService").IsEqual(Column.Parameter(true)).
                And("tos", "Id").IsEqual(Column.Parameter(BusinessServiceTypeId)).              
                And().OpenBlock
                               ("s", "TypeOfServiceRequestId").IsEqual(Column.Parameter(ServiceCallTypeUId)).
                               Or("o", "ServiceId").IsNull().
                               Or().OpenBlock
                                               ("s", "TypeOfServiceRequestId").IsEqual(Column.Parameter(IncidentTypeUId)).
                                               And().Exists(
                                                               new Select(UserConnection).Column("tech", "Id").From("Service").As("tech").
                                                               Where("tech", "ServiceParentId").IsEqual("s", "Id").
                                                               And("tech", "TypeOfServiceId").IsEqual(Column.Parameter(TechServiceTypeId)).
                                                               And("tech", "TypeOfServiceRequestId").IsEqual(Column.Parameter(ServiceCallTypeUId))
                                               ).
                               CloseBlock().
                CloseBlock() as Select;
 
using (var dbExecutor = UserConnection.EnsureDBConnection()) {
                using (var dr = offeringSelect.ExecuteReader(dbExecutor)) {
                               while (dr.Read()) {
                                               offeringList.Add((object)UserConnection.DBTypeConverter.DBValueToGuid(dr[0]));
                               }
                }
}
 
if (offeringList.Count == 0) {
                offeringList.Add((object)Guid.Empty);
}
 
 
 
e.Filters.Clear();
var filter = new Dictionary<string, object> { 
                               { "comparisonType", FilterComparisonType.Equal }, 
                               { "leftExpressionColumnPath", "Id" },
                               { "useDisplayValue", false }, 
                               { "rightExpressionParameterValues", offeringList.ToArray()}};
e.Filters.Add(filter);

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

Здравствуйте, Баглан!

Уточнил информацию у разработчиков.

Особенность фильтрации на PrepareLookupFilter состоит в том, что либо всё фильтруется через оператор “AND” (по умолчанию) либо через оператор “OR” (Логика устанавливается при помощи параметра)

e.ParametersValue.Add("logicalOperation", LogicalOperationStrict.Or);

Так как в примере идет пересечение AND и OR логики фильтрации, то остается более сложный путь:

1) Написать запрос, с помощью которого отберутся только те Id, которые удовлетворяют условию фильтрации;

2) В фильтрации PrepareLookupFilter фильтровать по найденным Id.

Пример реализации второго варианта:

List<object> offeringList = new List<object>();

var offeringSelect = new Select(UserConnection).

                Column("o", "Id").

                From("Offering").As("o").

                InnerJoin("OfferingType").As("ot").

                On("o", "TypeId").IsEqual("ot", "Id").

                InnerJoin("Service").As("s").

                On("o", "ServiceId").IsEqual("s", "Id").

                InnerJoin("TypeOfService").As("tos").

                On("s", "TypeOfServiceId").IsEqual("tos", "Id").

                Where("ot", "IsService").IsEqual(Column.Parameter(true)).

                And("tos", "Id").IsEqual(Column.Parameter(BusinessServiceTypeId)).              

                And().OpenBlock

                               ("s", "TypeOfServiceRequestId").IsEqual(Column.Parameter(ServiceCallTypeUId)).

                               Or("o", "ServiceId").IsNull().

                               Or().OpenBlock

                                               ("s", "TypeOfServiceRequestId").IsEqual(Column.Parameter(IncidentTypeUId)).

                                               And().Exists(

                                                               new Select(UserConnection).Column("tech", "Id").From("Service").As("tech").

                                                               Where("tech", "ServiceParentId").IsEqual("s", "Id").

                                                               And("tech", "TypeOfServiceId").IsEqual(Column.Parameter(TechServiceTypeId)).

                                                               And("tech", "TypeOfServiceRequestId").IsEqual(Column.Parameter(ServiceCallTypeUId))

                                               ).

                               CloseBlock().

                CloseBlock() as Select;

 

using (var dbExecutor = UserConnection.EnsureDBConnection()) {

                using (var dr = offeringSelect.ExecuteReader(dbExecutor)) {

                               while (dr.Read()) {

                                               offeringList.Add((object)UserConnection.DBTypeConverter.DBValueToGuid(dr[0]));

                               }

                }

}



if (offeringList.Count == 0) {

                offeringList.Add((object)Guid.Empty);

}







e.Filters.Clear();

var filter = new Dictionary<string, object> {

                               { "comparisonType", FilterComparisonType.Equal },

                               { "leftExpressionColumnPath", "Id" },

                               { "useDisplayValue", false },

                               { "rightExpressionParameterValues", offeringList.ToArray()}};

e.Filters.Add(filter);

С уважением,

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

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


Спасибо у меня получилось сделать.

"Бахгельдиев Баглан Абылаевич" написал:
Андрей Каспаревич пишет:

Здравствуйте, Баглан!

Уточнил информацию у разработчиков.

Особенность фильтрации на PrepareLookupFilter состоит в том, что либо всё фильтруется через оператор “AND” (по умолчанию) либо через оператор “OR” (Логика устанавливается при помощи параметра)

e.ParametersValue.Add("logicalOperation", LogicalOperationStrict.Or);

Так как в примере идет пересечение AND и OR логики фильтрации, то остается более сложный путь:

1) Написать запрос, с помощью которого отберутся только те Id, которые удовлетворяют условию фильтрации;

2) В фильтрации PrepareLookupFilter фильтровать по найденным Id.

Пример реализации второго варианта:

List<object> offeringList = new List<object>();

var offeringSelect = new Select(UserConnection).

                Column("o", "Id").

                From("Offering").As("o").

                InnerJoin("OfferingType").As("ot").

                On("o", "TypeId").IsEqual("ot", "Id").

                InnerJoin("Service").As("s").

                On("o", "ServiceId").IsEqual("s", "Id").

                InnerJoin("TypeOfService").As("tos").

                On("s", "TypeOfServiceId").IsEqual("tos", "Id").

                Where("ot", "IsService").IsEqual(Column.Parameter(true)).

                And("tos", "Id").IsEqual(Column.Parameter(BusinessServiceTypeId)).              

                And().OpenBlock

                               ("s", "TypeOfServiceRequestId").IsEqual(Column.Parameter(ServiceCallTypeUId)).

                               Or("o", "ServiceId").IsNull().

                               Or().OpenBlock

                                               ("s", "TypeOfServiceRequestId").IsEqual(Column.Parameter(IncidentTypeUId)).

                                               And().Exists(

                                                               new Select(UserConnection).Column("tech", "Id").From("Service").As("tech").

                                                               Where("tech", "ServiceParentId").IsEqual("s", "Id").

                                                               And("tech", "TypeOfServiceId").IsEqual(Column.Parameter(TechServiceTypeId)).

                                                               And("tech", "TypeOfServiceRequestId").IsEqual(Column.Parameter(ServiceCallTypeUId))

                                               ).

                               CloseBlock().

                CloseBlock() as Select;

 

using (var dbExecutor = UserConnection.EnsureDBConnection()) {

                using (var dr = offeringSelect.ExecuteReader(dbExecutor)) {

                               while (dr.Read()) {

                                               offeringList.Add((object)UserConnection.DBTypeConverter.DBValueToGuid(dr[0]));

                               }

                }

}

if (offeringList.Count == 0) {

                offeringList.Add((object)Guid.Empty);

}

e.Filters.Clear();

var filter = new Dictionary<string, object> {

                               { "comparisonType", FilterComparisonType.Equal },

                               { "leftExpressionColumnPath", "Id" },

                               { "useDisplayValue", false },

                               { "rightExpressionParameterValues", offeringList.ToArray()}};

e.Filters.Add(filter);

С уважением,

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

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

Спасибо у меня получилось сделать.

Добрый день, Андрей после переноса в боевую среду, начало выдавать ошибку, скрипт ниже,
LookupFilter не может принять записей больше 1000, высылаю скрин и текст ошибки, прошу помочь исправить ошибку, заранее спасибо.

Page.CallFromQueueEdit.PrepareLookupFilter += delegate (object sender, LookupEditEventArgs e) {
            List<object> callFromQueueList = new List<object>();
 
			var queryCallFromQueue = new Select(UserConnection)
			   .Column("a", "Id")
			   .From("Activity").As("a")
			   .Where("a", "TypeId").IsEqual(Column.Parameter(activityTypeId))
			   .And("a", "StartDate").IsLessOrEqual(Column.Parameter(UserConnection.CurrentUser.GetCurrentDateTime()))
			   .And("a", "StatusId").In(Column.Parameter(NotStartedStatusId), Column.Parameter(InWorkStatusId))
			   .And().OpenBlock("a", "DebtId").Not().IsNull()
			   .Or("a", "ReceivDebtId").Not().IsNull()
               .CloseBlock() as Select;
 
			using (var dbExecutor = UserConnection.EnsureDBConnection()) {
                   using (var dr = queryCallFromQueue.ExecuteReader(dbExecutor)) {
                          while (dr.Read()) {
                                 callFromQueueList.Add((object)UserConnection.DBTypeConverter.DBValueToGuid(dr[0]));
                          }
                   }
            }
			if (callFromQueueList.Count == 0) {
                callFromQueueList.Add((object)Guid.Empty);
            }
 
           e.Filters.Clear();
           var filter = new Dictionary<string, object> { 
                               { "comparisonType", FilterComparisonType.Equal}, 
                               { "leftExpressionColumnPath", "Id"},
                               { "useDisplayValue", false}, 
                               { "rightExpressionParameterValues", callFromQueueList.ToArray()}};
           e.Filters.Add(filter);
 
};

"Бахгельдиев Баглан Абылаевич" написал:
Бахгельдиев Баглан Абылаевич пишет:

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

Здравствуйте, Баглан!

Уточнил информацию у разработчиков.

Особенность фильтрации на PrepareLookupFilter состоит в том, что либо всё фильтруется через оператор “AND” (по умолчанию) либо через оператор “OR” (Логика устанавливается при помощи параметра)

e.ParametersValue.Add("logicalOperation", LogicalOperationStrict.Or);

Так как в примере идет пересечение AND и OR логики фильтрации, то остается более сложный путь:

1) Написать запрос, с помощью которого отберутся только те Id, которые удовлетворяют условию фильтрации;

2) В фильтрации PrepareLookupFilter фильтровать по найденным Id.

Пример реализации второго варианта:

List<object> offeringList = new List<object>();

var offeringSelect = new Select(UserConnection).

                Column("o", "Id").

                From("Offering").As("o").

                InnerJoin("OfferingType").As("ot").

                On("o", "TypeId").IsEqual("ot", "Id").

                InnerJoin("Service").As("s").

                On("o", "ServiceId").IsEqual("s", "Id").

                InnerJoin("TypeOfService").As("tos").

                On("s", "TypeOfServiceId").IsEqual("tos", "Id").

                Where("ot", "IsService").IsEqual(Column.Parameter(true)).

                And("tos", "Id").IsEqual(Column.Parameter(BusinessServiceTypeId)).              

                And().OpenBlock

                               ("s", "TypeOfServiceRequestId").IsEqual(Column.Parameter(ServiceCallTypeUId)).

                               Or("o", "ServiceId").IsNull().

                               Or().OpenBlock

                                               ("s", "TypeOfServiceRequestId").IsEqual(Column.Parameter(IncidentTypeUId)).

                                               And().Exists(

                                                               new Select(UserConnection).Column("tech", "Id").From("Service").As("tech").

                                                               Where("tech", "ServiceParentId").IsEqual("s", "Id").

                                                               And("tech", "TypeOfServiceId").IsEqual(Column.Parameter(TechServiceTypeId)).

                                                               And("tech", "TypeOfServiceRequestId").IsEqual(Column.Parameter(ServiceCallTypeUId))

                                               ).

                               CloseBlock().

                CloseBlock() as Select;

 

using (var dbExecutor = UserConnection.EnsureDBConnection()) {

                using (var dr = offeringSelect.ExecuteReader(dbExecutor)) {

                               while (dr.Read()) {

                                               offeringList.Add((object)UserConnection.DBTypeConverter.DBValueToGuid(dr[0]));

                               }

                }

}

if (offeringList.Count == 0) {

                offeringList.Add((object)Guid.Empty);

}

e.Filters.Clear();

var filter = new Dictionary<string, object> {

                               { "comparisonType", FilterComparisonType.Equal },

                               { "leftExpressionColumnPath", "Id" },

                               { "useDisplayValue", false },

                               { "rightExpressionParameterValues", offeringList.ToArray()}};

e.Filters.Add(filter);

С уважением,

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

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

Спасибо у меня получилось сделать.

Добрый день, Андрей после переноса в боевую среду, начало выдавать ошибку, скрипт ниже,

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

Page.CallFromQueueEdit.PrepareLookupFilter += delegate (object sender, LookupEditEventArgs e) {

            List<object> callFromQueueList = new List<object>();

           

                        var queryCallFromQueue = new Select(UserConnection)

                           .Column("a", "Id")

                           .From("Activity").As("a")

                           .Where("a", "TypeId").IsEqual(Column.Parameter(activityTypeId))

                           .And("a", "StartDate").IsLessOrEqual(Column.Parameter(UserConnection.CurrentUser.GetCurrentDateTime()))

                           .And("a", "StatusId").In(Column.Parameter(NotStartedStatusId), Column.Parameter(InWorkStatusId))

                           .And().OpenBlock("a", "DebtId").Not().IsNull()

                           .Or("a", "ReceivDebtId").Not().IsNull()

               .CloseBlock() as Select;

                           

                        using (var dbExecutor = UserConnection.EnsureDBConnection()) {

                   using (var dr = queryCallFromQueue.ExecuteReader(dbExecutor)) {

                          while (dr.Read()) {

                                 callFromQueueList.Add((object)UserConnection.DBTypeConverter.DBValueToGuid(dr[0]));

                          }

                   }

            }

                        if (callFromQueueList.Count == 0) {

                callFromQueueList.Add((object)Guid.Empty);

            }



           e.Filters.Clear();

           var filter = new Dictionary<string, object> {

                               { "comparisonType", FilterComparisonType.Equal},

                               { "leftExpressionColumnPath", "Id"},

                               { "useDisplayValue", false},

                               { "rightExpressionParameterValues", callFromQueueList.ToArray()}};

           e.Filters.Add(filter);



};

Здравтсвуйте, Баглан!
Как видно из текста ошибки, это ограничение Oracle. Его можно обойти, использовав логическую операцию "OR" для объединения каждых 999 идентификаторов в списке.
(http://stackoverflow.com/questions/17842453/is-there-a-workaround-for-o…)
Таким образом, Вы можете создать двухуровневый список, каждый список из которого будет включать 999 идентификаторов и затем добавить каждый список в отдельный фильтр. Чтобы установить логическую операцию объединения фильтров, используйте код:

e.ParametersValue.Add("logicalOperation", LogicalOperationStrict.Or);
Показать все комментарии

Элемент Чтение данных в событийном подпроцессе нельзя использовать?

Нравится

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

Здравствуйте, Александр!
Это действие нельзя использовать в процессе объекта, так как оно требует сериализации в БД, а процесс объекта не сериализируется.
Если это событийный подпроцесс в обычном БП, то использовать можно.
А в каком контексте возник данный вопрос?

да я сам понял уже, просто хотелось попроще :-)

Показать все комментарии
добавление записей в деталь
Технические вопросы
5.x

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

Нравится

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

Илья, уточните, пожалуйста, что Вы имеете ввиду.
Если я правильно понял, то имеются виду вкладки с деталями на карточке редактирования:

Чтобы они появились в карточке необходимо для карточки редактирования раздела в "Рабочих местах" указать признак "Добавить в карточку детали раздела":

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

Андрей, не так.

Есть, например, карточка продажи с деталью "контрагенты"

Необходимо при заполнении поля "Группа компаний", добавить на деталь "контрагенты", контрагентов из выбранной группы.

Илья, а после сохранения записи они там появляются?

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

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

Реализовал вот так:

Guid affiliationId = Guid.Parse(Page.AffilationEdit.Value.ToString());
 
var userConnection = Page.UserConnection;
var entitySchemaManager = Page.Schema.SchemaManagerProvider.GetManager("EntitySchemaManager") as Terrasoft.Core.Entities.EntitySchemaManager;
var entitySchemaQuery = new EntitySchemaQuery(entitySchemaManager, "AccountToAffiliation");
var accountColumnName = entitySchemaQuery.AddColumn("Account").Name;
entitySchemaQuery.Filters.Add(entitySchemaQuery.CreateFilterWithParameters(FilterComparisonType.Equal, "Affiliation", affiliationId));
var accountCollection = entitySchemaQuery.GetEntityCollection(UserConnection);
 
Guid accountId;
var accountInOpportunityEntitySchema = UserConnection.EntitySchemaManager.GetInstanceByName("AccountInOpportunity");
foreach (var record in accountCollection) {
  accountId = record.GetTypedColumnValue<Guid>("AccountId");
 
  var accountInOpportunityEntity = accountInOpportunityEntitySchema.CreateEntity(UserConnection);
  accountInOpportunityEntity.SetDefColumnValues();
  accountInOpportunityEntity.SetColumnValue("OpportunityId", EntityPrimaryColumnValue);
  accountInOpportunityEntity.SetColumnValue("AccountId", accountId);
  accountInOpportunityEntity.Save();
}

Илья, рад, что получилось.
Спасибо, что делитесь решениями.)

Показать все комментарии
карточка редактирования
колонки
обработчик события
Технические вопросы
Разработка

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

Не могу найти соответствующий обработчик события.

Не могу найти саму форму "Выбор 'Платежные реквизиты'", которая открывается.

Нравится

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

"Алейник Алексей Вадимович" написал:Не могу найти саму форму "Выбор 'Платежные реквизиты'"

Потому что там наверняка используется wnd_SelectData
Чтобы отобразились какие-то другие колонки - установите для них признак "Колонка для отображения" в сервисе датасета.

Спасибо, Вы были правы.

Однако, всё равно интересно где указывается обработчик события, которое открывает форму wnd_SelectData по щелчку левой кнопкой мыши на объекте LookupDateControl?

окно указывается в свойстве SelectWindowUSI для элемента ILookupDataControl

SDK

Показать все комментарии
css
элемент управления
Технические вопросы
7.x

Доброго времени суток!
Есть задача расположить 2 элемента управления в одну строку: поле справочника "Страна" и булево "Резидент" в карточке модуля (наподобие элементов напоминания автору и ответственному в активности). CSS-правило для этого не проблема, проблема в другом - где его расположить, ведь в схеме карточки css'ы не хранятся. Замещать только ради этого CardModule - не вариант. Пробовал создать свой модуль, в котором определил нужные правила. В нужной карточке подгружаю его

sandbox.loadModule('MyUtilsModule');

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

Нравится

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

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

CustomConfig {
styles: {
wrapStyles: {
'float': 'left'
}
}
}

"Ильюша Сергей Николаевич" написал:

CustomConfig {

styles: {

wrapStyles: {

'float': 'left'

}

}

}


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

Вопрос снимается - проблема решилась

Как подскажите ? на будущее ?

this.bindings."имя элемента, для которого нужно применить стили" = {
    styles: {
        wrapStyle: {
            float: 'right'
        }
    }
}

итог - inline-стиль элемента.
Вариант, конечно, кривоват и удобен, если только нужно "накинуть" 1-2 правила на 1-2 элемента, но все же имеет место жить

Показать все комментарии
Технические вопросы
Разработка

Здравствуйте. Сформировал запрос в сервисе SelectQuery на колонках с собственным текстом SQL.
Получилось:

SELECT
       
  /* AS [Go],
        */

[tbl_CustomDatesTable].[Comment] AS [Comment],
        [tbl_CustomDatesTable].[Date] AS [Date],
        [tbl_CustomDatesTable].[ID] AS [ID] /* AS [ID],
        */

FROM dbo.tbl_CustomDatesTable
WITH (nolock)
IF 1=0
SELECT 1 AS [Finish]
FROM
        [dbo].[tbl_Account] AS [tbl_Account];

Однако, справочник таким образом не открывается, на обычном SelectQuery с конструкторными колонками все нормально. Недоработка или что? Для каждого столбца специально также была взята отдеальная колонка с текстом. Объясните пожалуйста в чем проблема и причины отсутствия возможности формирования датасета таким методом.

Нравится

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

Такое ощущение что террасофт просто забивает на то что закомментировано и пытается все железно забрать и конструкторского FROM

"Нестеров Артем Валерьевич" написал:справочник таким образом не открывается

может быть ошибку какую-то дает?

приведенный текст запроса взят откуда? хорошо бы его надо взять из предпросмотра в сервисе SelectQuery или из профайлера

"Андросов Дмитрий" написал:Нестеров Артем Валерьевич пишет:

справочник таким образом не открывается

может быть ошибку какую-то дает?

приведенный текст запроса взят откуда? хорошо бы его надо взять из предпросмотра в сервисе SelectQuery или из профайлера

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

Ну и плюс убрал комментарии из полей, которые отображаются. Вот так открывает:

SELECT
 
  /* AS [Go],
	*/
[tbl_CustomDatesTable].[CreatedOn] AS [CreatedOn],
	[tbl_CustomDatesTable].[Comment] AS [Comment],
	[tbl_CustomDatesTable].[Date] AS [Date],
	[tbl_CustomDatesTable].[ID] AS [ID],
	[tbl_CustomDatesTable].[ModifiedOn] AS [ModifiedOn]/* AS [ModifiedOn],
	*/
FROM dbo.tbl_CustomDatesTable
with (nolock)
IF 1=0
SELECT 1 AS [Finish]
FROM
	[dbo].[tbl_CustomDatesTable] AS [tbl_CustomDatesTable]

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

ничего не пишите в последней кастомной колонке, но создайте CustomSQL-фильтр с текстом

*/--

Вышел такой текст запроса:

SELECT
 
  /* AS [Go],
	*/
[tbl_CustomDatesTable].[CreatedOn] AS [CreatedOn],
	[tbl_CustomDatesTable].[Comment] AS [Comment],
	[tbl_CustomDatesTable].[Date] AS [Date],
	[tbl_CustomDatesTable].[ID] AS [ID],
	[tbl_CustomDatesTable].[ModifiedOn] AS [ModifiedOn]/* AS [ModifiedOn],
	*/
FROM [dbo].[tbl_CustomDatesTable] AS [tbl_CustomDatesTable]
with (nolock)
/* AS [Finish]
FROM
	[dbo].[tbl_CustomDatesTable] AS [tbl_CustomDatesTable]
WHERE(*/--)

Самому все нравится, но террасофт походу отказывается его понимать и не хочет открывать справочник с этими полями

Может какие то правила синтаксиса? Или все таки то что я делаю - нереализуемо в террасофте? Прошу помощи

Поймали запрос из Террасофта на сервере и выяснилось что ни нолок, ни половина запроса указанные за комментариями не передается. Железно передается закоменченная таблица из второго FROM! И параметры столбцов. Это мы чего-то не понимаем или тут действительно такое накручено?

А когда отловили из предзапуска предпропросмотра - передался полноценный текст запроса...И как с этим работать, собственно говоря, если это не работает?

выложите сервисы :wink:

в сервисе датасета не выбран сервис запроса на выборку. Вернее там стоит sq_CustomDatesSelect

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

Здравствуйте, Артем!
В Terrasoft не реализована возможность добавления табличных указаний. При разборе запроса ядром системы используется тот блок FROM, который задается в соответствующем поле, поэтому даже если его закомментировать, он все равно будет использоваться, поэтому хитрости с комментариями не проходят.

Показать все комментарии
Технические вопросы
Разработка

Здравствуйте. Имеем датасет, в котором хранятся даты(день, месяц, год) + комментарий.
Имеется поле для установки даты, значение которого назовем var1(не из вышеуказанного датасета).

Как проверить, имеется ли в датасете запись со значением из поля var1?

Грубо говоря проверить примерно такое условие var1 == Dataset('Dates'). Но по логике то что написано это сравнение значения переменной с целым массивом данных, как пробежаться грубо говоря по каждой записи и сравнить нет ли с одной из них совпадения? Учитывается только дата, без комментария.

Нравится

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

Если и там и там именно дата, без времени (то есть возможно строгое совпадение), то можно в SelectQuery датасета создать фильтр по полю с датой. Потом в скрипте налагать на датасет этот фильтр с помощью функции ApplyDatasetFilter, открывать датасет и смотреть, не пуст ли он.

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

    var Dataset = Services.getNewItemByUSI('ds_Какой-то датасет');
	RefreshDataset(Dataset);
	//Тут я получил сегодняшнее число без времени
	var var1 = new Date();
	var1.setHours(0,0,0,0);
	var1 = var1.getVarDate();
 
	var result = false;
	Dataset.GoToFirst();
	while(!Dataset.IsEOF) {
		if (DateToStr(Dataset('Dates')) == DateToStr(var1)) {
			result = true;
			break;
		}
		Dataset.GoToNext();
	}
	if (result) Log.Write(1, 'Есть совпадение');
	else Log.Write(1, 'Нет совпадений');

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

Показать все комментарии
bpm
сохранение записи
Технические вопросы
5.x

Здравствуйте!
Подскажите, пожалуйста, как можно реализовать следующий функционал. Хочу при сохранении записи делать проверку и при определенных условиях не давать сохранять запись и выводить сообщение. Так вот для этого я в событие "Перед сохранением" моего объекта написал скрипт с моей проверкой и возвращал в нем false если не хотел сохранять запись. Но запись все равно сохраняется. Подскажите, пожалуйста что можно сделать чтобы это заработало и как еще вывести в MessagePanel сообщение о причинах при которых эта запись не сохраняется(аналог указан на картинке). Спасибо!

Нравится

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

Может вру, но вот в тройке я возвращаю true, чтобы запись не сохранялась, может и в BPM 5.х также!?
А на счет MessagePanel почитайте тут

Здравствуйте, Павел!
Можно добавить проверки в обработчик нажатия кнопки "ОК" и устанавливать булевский параметр в false, если проверка не прошла. А после Вашего скрипта ставить условный поток, который будет идти дальше в зависимости от параметра.

Можно повесить проверку на нажатие кнопки ОК.
OKBtnClick

В нижнем блоке:

Page.BaseMessagePanel.AddMessage(Warning, MyTextOfMessage, MessageType.Warning);
return true;

Спасибо! Помогло)

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

Вопрос: как это реализовать через стандартную кнопку?

ScriptTask2:

var AccountAddressCLADR =  UserConnection.EntitySchemaManager.GetInstanceByName("AccountAddressCLADR");
var entity = AccountAddressCLADR.CreateEntity(UserConnection);
var contactId = Page.DataSource.ActiveRowPrimaryColumnValue;
if(contactId == Guid.Empty ){
	Page.ThrowEvent("SaveContactNeeded");
	return true;
}
IsCanDelete = true;
if (entity.FetchFromDB(contactId)) {
 IsCanDelete = !entity.GetTypedColumnValue<Boolean>("ByDefault");
}
return true;

ScriptTask1:

string warningMessageId = "SomeMessageId";
string errorMessage = "Нельзя удалить адрес с установленным признаком <По умолчанию>";
MessagePanel messagePanel = ControlUtilities.FindControl(
                Page.AspPage.Controls[0], "BaseMessagePanel", true) as MessagePanel;
if (messagePanel != null) {
                messagePanel.Remove(warningMessageId);
                messagePanel.AddMessage(warningMessageId, Warning, errorMessage, MessageType.Warning);
}
return true;

На стандартную кнопку навешивается js-обработчик, см. в функции ScriptRegisterClientScriptExecute, унаследованной из BaseGridPage.

	public virtual bool ScriptRegisterClientScriptExecute(ProcessExecutingContext context) {
			string formatString = "{0}.on('click', function(el) {{ {1} }}, this)";
string script = GetRegisterQuestionScript();
if (!string.IsNullOrEmpty(script)) {	
	Page.AddScript(string.Format(formatString, Page.DeleteButton.ClientID, script));
}
...

Чтобы его отключить, можно в функции GetRegisterQuestionScript в своей странице написать вначале

return string.Empty; 

вместо логики.

Показать все комментарии
условный поток
Технические вопросы
7.x

Здравствуйте!
Есть такая задача:

В начале процесса может быть выбран один или несколько продуктов двух типов, и если выбран хотя бы один продукт типа, то маркер этого типа устанавливается в 1

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

На данный момент процесс перестает работать при выбора варианта ответа "Оплата получена".
Что я делаю не так?

Нравится

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

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

Первое, используйте элемент "Исключающий или" (с крестиком) .
Второе: используйте поток по умолчанию и условные потоки. Нельзя использовать безусловный поток.

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