ItemAlreadyExistsException
мастер деталей
Технические вопросы
7.x

Добрый день коллеги! Помогите пожалуйста избавиться от ошибки.
При отрытии мастера деталей - вылетает :

basecollection.js:20 Uncaught Terrasoft.ItemAlreadyExistsException: Элемент с ключём "771456ac-bf0a-494d-9136-086080423d03" Уже существует

сделал поиск по ключу - это id детали, из таблицы sysDetail. Можно ли как то обойти эту ошибку без удаления детали? или единственный выход удалить и заново зареестрировать деталь?

Нравится

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

Здравствуйте, Влад.

Вам необходимо удалить деталь.
Почистить за ней все в БД
И заново создать её.

ок, спасибо за быстрый ответ!

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

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

Версия BPM 7.6.0.1265, развернута OnSite.

Используя Terrasoft.Sync в БП вывожу сообщение в консоль браузера:

SyncMsgLogger _clientLogger = new SyncMsgLogger((UserConnection)context.UserConnection, Guid.Empty);
_clientLogger.LogInfo("ProcessStart");
UsrTest.TestWriteLog();

или используя код в классе:
public static class UsrTest
{
        private static SyncMsgLogger _clientLogger;
        internal static SyncMsgLogger ClientLogger {
                get {
                        return _clientLogger != null ? _clientLogger : (_clientLogger = new SyncMsgLogger((UserConnection)HttpContext.Current.Session["UserConnection"], Guid.Empty));
                }
        }
       
        public static void TestWriteLog()
        {
                ClientLogger.LogInfo("TestWriteLog");
        }
}

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

В обоих случаях процесс завершается без ошибок. Подскажите пожалуйста в чем может быть проблема? И какие еще есть варианты отладки, без доступа к машине на которой развернута BPM?

Нравится

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

Здравствуйте.
Во вложении - рекомендации по использованию логгера log4net (возможно будут полезными).

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

Коллеги, подскажите пож-та.
Есть необходимость добавить дополнительное поле
Как добавить поле "Название страны на анг" в справочник "страна" ?

Нравится

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

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

Ответили в рамках поддержки, но может кому-то еще понадобится.
Данная задача может быть выполнена следующим образом:
0) Перйдите в конфигурацию
1) Добавьте поле в объект "Страна" (поле с типом строка). Вы можете добавить это поле, заместив объект "Страна"
2) Добавьте схему с типом "Замещающая страница". Схему с типом "Замещающая страница" Вы можете найти в расширенном представлении кнопки "Добавить"
3) Выберите в качестве родительской страницы страницу "Страница редактирования страны"
4) В MainContolLayout Вам необходимо добавить элемент "Текстовое поле" (выделите MainContolLayout и нажмите правой кнопкой мышки, чтобы открыть доступные варианты)
5) Выделите добавленное поле в структуре и переместите его на нужное место (обычное перетаскивание мыши)
6) В свойствах этого поля укажите "Источник данных" - DataSource, Колонка данных - созданная на первом шаге колонка объекта "Страна".
7) Сохраните и опубликуйте страницу.

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

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

Добрый день!

Бизнес-кейс:
Необходимо у контакта делать пометки к средствам связи. Например, "конкретный телефон - телефон бабушки" или "по этому номеру не звонить после 21.00".

Как возможно добавить комментарий к каждому средству связи в детали communication options стандартным функционалом (не отказываясь от этой детали)?

Спасибо!

Нравится

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

Деталь «Средства связи является» не простой деталью так как она формируется динамически и кардинально отличается от обычных деталей. Мы не рекомендуем вносить исправления в данную деталь, так как Вы можете нарушить логику ее заполнения.
Для внесения изменений в деталь средства связи Вам необходимо будет заместить объект "ContactCommunication" и добавить текстовое поле с произвольным названием. Расширить страницу ContactCommunicationDetailV2, переопределить метод getItemViewConfig.
Ниже, как пример (в случае если новое поле назвать Comment). Изменения выделены комментариями. Можете также попробовать сделать по другому с вызовом родительского метода.

getItemViewConfig: function(itemConfig) {
var itemViewConfig = this.get("itemViewConfig");
if (itemViewConfig) {
itemConfig.config = itemViewConfig;
return;
}
var config = ViewUtilities.getContainerConfig("item-view",
["detail-edit-container-user-class", "control-width-15"]);
var typeMenuItems = [];
var communicationTypes = this.get("CommunicationTypes");
communicationTypes.each(function(item) {
var name = item.get("Name");
var value = item.get("Id");
typeMenuItems.push({
id: value,
caption: name,
tag: value,
click: { bindTo: "typeChanged" }
});
}, this);
var typeButtonConfig = {
id: "type",
className: "Terrasoft.Button",
classes: {
wrapperClass: ["label-wrap", "detail-type-btn-user-class"],
textClass: ["detail-type-btn-inner-user-class"]
},
style: Terrasoft.controls.ButtonEnums.style.TRANSPARENT,
selectors: {wrapEl: "#type"},
caption: {
bindTo: "CommunicationType",
bindConfig: { converter: "typedStringValueConverter" }
},
menu: { items: typeMenuItems }
};
var deleteButtonConfig = {
id: "delete",
className: "Terrasoft.Button",
classes: {
wrapperClass: "detail-delete-btn-user-class",
imageClass: ["detail-delete-btn-image-user-class", "close-button-background-no-repeat"]
},
imageConfig: resources.localizableImages.DeleteIcon,
style: Terrasoft.controls.ButtonEnums.style.TRANSPARENT,
selectors: {wrapEl: "#delete"},
click: {bindTo: "deleteItem"}
};
var editConfig = {
id: "edit",
className: "Terrasoft.TextEdit",
classes: {wrapClass: ["communication-lookup-img-user-class", "detail-edit-user-class"]},
rightIconClasses: ["lookup-edit-right-icon"],
value: { bindTo: "Number" },
readonly: {
bindTo: "CommunicationType",
bindConfig: { converter: "isSocialNetworkType" }
},
enableRightIcon: {
bindTo: "CommunicationType",
bindConfig: { converter: "isSocialNetworkType" }
},
rightIconClick: { bindTo: "onLookUpClick" }
};
//Начало исправления
var commentConfig = {
id: "comment",
className: "Terrasoft.TextEdit",
value: { bindTo: "Comment" },
};
//Завершение исправления
config.items.push(typeButtonConfig, editConfig, deleteButtonConfig, commentConfig); //добавляем commentConfig

itemConfig.config = config;
this.set("itemViewConfig", config);
},

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

Коллеги, приветствую.

Есть некоторый запрос к базе данных, полученный с использованием класса SELECT (считывается информация о платежах за период по ФИО должника.):

var selectPaymentsRegister = (Select)new Select(userConnection)
        .Column("c", "Surname").As("Surname")
        .Column("c", "GivenName").As("Name")
        .Column("c", "MiddleName").As("MiddleName")
        .Column("c", "Name").As("FullName")
        .Column("c", "Phone").As("Phone")
        .Column("c", "Address").As("Address")
        .Column("up", "UsrPaymentSum").As("Amount")
        .Column("up", "UsrPaymentDate").As("AmountDate")
        .From("UsrPayments").As("up")
        .Join(JoinType.Inner, "Contact").As("c")
        .On("up", "UsrDebtorId").IsEqual("c", "Id")
        .Where("c", "Surname").IsEqual(Column.Parameter(debtorSurname))
        .And("c", "GivenName").IsEqual(Column.Parameter(debtorName))
        .And("c", "MiddleName").IsEqual(Column.Parameter(debtorMiddleName))
        .And("up", "UsrPaymentDate").IsGreaterOrEqual(Column.Parameter(dateBegin))
        .And("up", "UsrPaymentDate").IsLessOrEqual(Column.Parameter(dateEnd))

        as Select;

Далее, с использованием IDataReader в цикле я получаю значения полей.

Как составить такой же запрос, но с использованием EntitySchemaQuery? Хочу подробнее разобраться в этой теме.

Был бы весьма признателен за информацию.

Спасибо.

--
С уважением, Алексей Быков.

Нравится

2 комментария
Like
запрос
Технические вопросы
7.x

Добрый день!
Бывают к примеру фильтры сравнения
filterGroup1.add("ServiceItemFilter", scope.Terrasoft.createColumnFilterWithParameter(
scope.Terrasoft.ComparisonType.EQUAL, "[ServiceEngineer:Engineer].ServiceItem", serviceItem.value));
}

фильтры проверки на null
filterGroup2.add("TerritoryNullFilter", scope.Terrasoft.createColumnIsNullFilter(
"[ServiceEngineer:Engineer].UsrNeedTerritory"));

А подскажите, пожалуйста, синтаксис фильтра like?
Допустим, я хочу исключить все группы в название которых входит Группа руководителей
Каков синтакис?

Нравится

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

Попробуйте, использовать для этой задачи NOT IN фильтр на ESQ?

var existsFilter = this.Terrasoft.createColumnInFilterWithParameters("Id",
   someCollection);
existsFilter.comparisonType = this.Terrasoft.ComparisonType.NOT_EQUAL;

вы имеете в виду создать коллекцию someCollection, в которую бы входили группы с названием "Группа руководителей", а потом ее исключить из выбора?
Да, наверное, это вариант.
Хорошо, спасибо, попробую

вы имеете в виду создать коллекцию someCollection, в которую бы входили группы с названием "Группа руководителей", а потом ее исключить из выбора?
Да, наверное, это вариант.
Хорошо, спасибо, попробую

хотя вопрос остается)
даже если это фильтр на ESQ

Допустим, есть такой фильтр
- этот фильтр отбирает записи, у которых поле UsrTest = значению somecaption
esq.filters.add("filterCase", Terrasoft.createColumnFilterWithParameter(
Terrasoft.ComparisonType.EQUAL, "UsrTest", somecaption));
каким образом должен выглядеть фильтр, отбирающий записи, в название которых (поле UsrTest в примере) входит значение somecaption?

Здравствуйте, Дарья!

1) Откройте консоль браузера, находясь в Вашей CRM системе
2) Начните писать в консоли Terrasoft.ComparisonType.
В результате система Вам предложит все типы сравнения - просто выберите нужный. В условиях Вашей задачи - это CONTAIN.

Спасибо, Алексей, попробую

Показать все комментарии
NET Framework 4.5
soap
WCF
Web-сервис
wsdl
аутентификация
Технические вопросы
7.x

Коллеги, приветствую.

Пытаюсь аутентифицировать внешние запросы к WCF Web- сервису. Для этого передаю логин и пароль в заголовке SOAP.

using (UsrService client = new UsrService())
{
        client.Credentials = new System.Net.NetworkCredential("Пользователь 1", "Пользователь 1");
        client.SayHello();
}

И Web- сервис и его клиент работают на платформе .NET Framework 4.5.

Запрос не проходит аутентификацию и, насколько я понимаю, происходит редирект на форму логина.

http://localhost:8080/NuiLogin.aspx?ReturnUrl=%2f0%2fServiceModel%2fSimpleCustomService.svc

Что я вижу в своем консольном клиенте:

С чем это может быть связано?

Был бы весьма признателен за информацию.

Спасибо.

--
С уважением, Алексей Быков.

Нравится

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

Если в клиенте я добавляю:

client.AllowAutoRedirect = true;

То в консоли вижу следующее:

Необработанное исключение: System.InvalidOperationException: Клиент обнаружил ти
п содержимого ответа "text/html; charset=utf-8", но ожидается тип "text/xml".
Сбой запроса с сообщением об ошибке:
--
 
 
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.or
g/TR/xhtml1/DTD/xhtml1-transitional.dtd">
 
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="X-UA-Compatible" content="IE=Edge" /><meta http-equiv="C
ontent-Type" content="text/html; charset=utf-8" /><link href="favicon.ico" rel="
shortcut icon" type="image/vnd.microsoft.icon" /><title>
        bpm'online bank customer journey
</title>
        <style>
                .login-label-logo
                {
                        background: url("terrasoft.axd?s=nui-binary-syssetting&r
=Logoimage");
                        background-repeat: no-repeat;
                        width: 223px;
                        height: 100px;
                        margin-bottom: 28px;
                        background-position: left bottom;
                }
        </style>
<script type="text/javascript">
window.workspaceList = {'1': { value: 'Default', displayValue: 'Default' }};
window.supportInfo = [];
window.supportInfoCaption = '';
window.importantLinks = [];
window.importantLinksCaption = '';
window.productVersion = '7.7.0.2872';
window.loginTimeout = '30000';
window.workspaceCount = 1;
var Terrasoft = Terrasoft || {};
window.isNtlmLoginVisible = false;
</script>
<script type="text/javascript" src="http://localhost:8080//core-sl/3218931132877
873a78c92ded6a0b0cf/Terrasoft.Nui"></script>
<script type="text/javascript">
var Terrasoft = Terrasoft || {};
Terrasoft.loaderBaseUrl = 'http://localhost:8080/';
Terrasoft.workspaceBaseUrl = 'http://localhost:8080/';
</script>
<script type="text/javascript">
var FileAPI = {
        staticPath: '../Resources/ui/FileAPI/',
        flashUrl: '../Resources/ui/FileAPI/FileAPI.flash.swf',
        flashImageUrl: '../Resources/ui/FileAPI/FileAPI.flash.image.swf' };
</script>
<script type="text/javascript">
var Terrasoft = Terrasoft || {};Terrasoft.enablePerformanceManager = false;</scr
ipt>
<!--[if IE 8]>
<script type="text/javascript" src="http://localhost:8080//core/b812d8cf89ec068b
5cdda18f2d0de397/normalize/es5shim.js"></script>
<![endif]-->
<script type="text/javascript" src="http://localhost:8080//core/db7fe0930e6258f0
1fb73405039cc9a5/normalize/classList-shim.js"></script>
<script type="text/javascript" src="http://localhost:8080//core/824fc2789913efd8
506c23cfd39496e8/history/history.js"></script>
<script type="text/javascript" src="http://localhost:8080//core/b515858f8b0235cd
de97a34f56882a5b/combined/all-combined.js"></script>
<link rel="stylesheet" type="text/css" href="http://localhost:8080//core/d9868b8
8e2b56f0964c6c0146598e324/combined/all-combined.css" />
<link rel="stylesheet/less" type="text/css" href="http://localhost:8080//core/7e
1adee4ce5c31795a7bb8819c10aeb8/combined/all-combined.less" />
<script type="text/javascript" src="http://localhost:8080//core/48bca5c68f167104
05127cce054f5534/requirejs/require.js"></script>
<script type="text/javascript">
requirejs.config({
paths: {
'core':'http://localhost:8080//core/ef58ab72c648daaa7af074e2526dffc3/Terrasoft/a
md/core',
'bootstrap':'http://localhost:8080//core/022b4acc49ebfbfb33b54d4f95393d2a/Terras
oft/amd/bootstrap',
'performancecountermanager':'http://localhost:8080//core/3bf271e2ad15f056eac25ab
fea30226a/Terrasoft/amd/performancecountermanager',
'loadbootstrap':'http://localhost:8080//core/b0ebbf0e263a02a3db86bf39761aba1c/Te
rrasoft/amd/bootstrap.login',
'jQuery':'http://localhost:8080//core/8d24859b5ac713ab6f05091492b6c631/jQuery/jQ
uery',
'jQuery-easing':'http://localhost:8080//core/a6f75e0c043a2a087837e5c113cc6f7a/jQ
ueryEasing/jQuery-easing',
'jsrender':'http://localhost:8080//core/77f59dfac75bba6c861fe26d75691086/jsrende
r/jsrender',
'ej-common-all':'http://localhost:8080//core/e8b46aebd6473a2f85386c0d072a2b93/Sy
ncfusion/min/ej-common-all',
'ej-diagram':'http://localhost:8080//core/89f5be5f51b070471058224a6550b99a/Syncf
usion/min/ej-diagram',
'process-schema-diagram':'http://localhost:8080//core/650e4ae64a84c1fd11caab7904
39c8ef/Terrasoft/designers/process-schema-designer/process-schema-diagram',
'process-schema-diagram-5x':'http://localhost:8080//core/b0b08b3ec18e7494d488622
07309479f/Terrasoft/designers/process-schema-designer/process-schema-diagram-5x'
,
'ckeditor-base':'http://localhost:8080//core/04628941838af9176121c9cd4332b49d/CK
Editor/ckeditor',
'html2canvas':'http://localhost:8080//core/524ae0cfb507a786266d32d9a16ccc42/html
2canvas/html2canvas'
},
shim: {'jQuery-easing': {'deps': ['jQuery']}, 'ej-common-all': {'deps': ['jQuery
-easing']}, 'ej-diagram': {'deps': ['ej-common-all', 'jsrender']}, 'process-sche
ma-diagram': {'deps': ['ej-diagram']}, 'process-schema-diagram-5x': {'deps': ['p
rocess-schema-diagram']}}});
require(['loadbootstrap'],function() {});
</script>
<script type="text/javascript">
var Terrasoft = Terrasoft || {};
Terrasoft.isDebug = false;
Terrasoft.DataValueTypeRange = {INTEGER: {maxValue:2147483647,minValue:-21474836
48},FLOAT: {maxValue:79228162514264337593543950335,minValue:-7922816251426433759
3543950335},DATE_TIME: {maxValue:"0001-01-01T00:00:00.000",minValue:"0001-01-01T
00:00:00.000"}};
Terrasoft.storesConfig = [];
Terrasoft.storesConfig.push({levelName: 'ClientPageSession', type: 'Terrasoft.Me
moryStore', isCache: true});Terrasoft.storesConfig.push({levelName: 'Domain', ty
pe: 'Terrasoft.LocalStore', isCache: true});
if(Terrasoft.StoreManager){
        Terrasoft.StoreManager.registerStores(Terrasoft.storesConfig);
}
 
</script>
</head>
<body>
        <form name="IndexForm" method="post" action="./NuiLogin.aspx?ReturnUrl=%
2f0%2fServiceModel%2fSimpleCustomService.svc%2fsoap" id="IndexForm">
<div>
<input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="Ael0TejuuQ2cn+6a
KrS5wJo2ATMwUDq1DBRh5WGdOqpW+NOyOwBLY85L9xsvJnX+0sZlKI3bZN5Qk7o0okrcDBSteeTArKGx
leRg/1ydqd/XMABb" />
</div>
 
<div>
 
        <input type="hidden" name="__VIEWSTATEGENERATOR" id="__VIEWSTATEGENERATO
R" value="F2DA7F48" />
</div>
        </form>
</body>
</html>
 
--.
   в System.Web.Services.Protocols.SoapHttpClientProtocol.ReadResponse(SoapClien
tMessage message, WebResponse response, Stream responseStream, Boolean asyncCall
)
   в System.Web.Services.Protocols.SoapHttpClientProtocol.Invoke(String methodNa
me, Object[] parameters)
   в UsrService.SayHello() в c:\VS2015\Projects\WCFSharedDLL\WCFSharedDLL\TestPr
oxyClass.cs:строка 44
   в ConsoleApplicationForTesting.Program.Main(String[] args) в c:\VS2015\Projec
ts\ConsoleApplicationForTesting\ConsoleApplicationForTesting\Program.cs:строка 1
6
Для продолжения нажмите любую клавишу . . 

Т.е. исходный код страницы авторизации.

Решил таким образом. На уровне транспортного протокола передал учетные данные:

public const string authServiceUri = 
	"http://localhost:8080/ServiceModel/AuthService.svc/Login";
public static CookieContainer AuthCookie = 
	new CookieContainer();
 
public static bool TryLogin(string userName, string userPassword)
{
    var authRequest = HttpWebRequest.Create(authServiceUri) 
		as HttpWebRequest;
 
    authRequest.Method = "POST";
    authRequest.ContentType = "application/json";
    authRequest.CookieContainer = AuthCookie;
 
    using (var requesrStream = authRequest.GetRequestStream())
    {
        using(var writer = new StreamWriter(requesrStream))
        {
            writer.Write(@"{
                ""UserName"":""" + userName + @""",
                ""UserPassword"":""" + userPassword + @"""
            }");
        }
    }
 
    using(var response = (HttpWebResponse)authRequest.GetResponse())
    {
        if (AuthCookie.Count > 0)
        {
            return true;
        }
    }
    return false;
}

Установил CookieContainer:

client.CookieContainer = AuthCookie;

Стало возможным выполнять запросы к Web- сервису:

static void Main(string[] args)
{
	using (UsrService client = new UsrService())
	{
		if(TryLogin("Пользователь 1", "Пользователь 1"))
		{
			client.CookieContainer = AuthCookie;
			Console.WriteLine(client.SayHello());
		}
	}
}

Хотя и осталось непонятным, почему не удалось аутентифицировать внешние запросы через передачу учетных данных в SOAP заголовке...

Здравствуйте.
Как вариант, в заголовок запроса можно было попробовать указать content-type "text/xml".

Здравствуйте, Александр. Хорошо, спасибо - попробую и отпишусь, что вышло.

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

Добрый день! Подскажите, пожалуйста, какие есть функции для того, чтобы рассчитать дату.

Например есть одна дата,
и необходимо рассчитать другую дату 2 = как дата 1 + столько дней/месяцев

Спасибо

Нравится

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

Думаю, ответ тут - про методы DateTime C#
А если на клиенте, то javascript здесь

на клиенте, да.
в скриптах карточек..

Значит что-то вроде

var newDate = CurrentDate.setMonth(CurrentDate.getMonth() + x);

хотя правильнее

var newDate = new Date(CurrentDate.getTime() + days * 24*60*60*1000);

Спасибо

Добрый день!
Хочу в элементе процесса (добавление данных)
рассчитать дату
вот таким образом, например,
[#Системная переменная.Текущее значение даты#].AddMonths(1)

Но при сохранении процесса возникает ошибка

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

Здравствуйте, Дарья!

Вместо [#Системная переменная.Текущее значение даты#] используйте System.DateTime.Now

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

Добрый день! Подскажите, пожалуйста, какие есть функции для того, чтобы рассчитать дату.

Например есть одна дата,
и необходимо рассчитать другую дату 2 = как дата 1 + столько дней/месяцев

Спасибо

Нравится

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

Здравствуйте!
Скажите пожалуйста как в БП посчитать количество дней в текущем месяце в которых например было 30 исходячих звонков длительностью больше 30 сек?

И как посчитать в БП количество всего робочих дней в этом месяце ?
Спасибо!

Нравится

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

Добрый день.
1. Кол-во дней в месяце с заданными условиями
1. Определить временной интервал (начало и конец периода). Например, добавить параметры startDate, endDate, oneDay (startDate.AddDays(1)).
2. Добавить счетчик. Параметр в котором будет хранится кол-во дней c интересующими условиями.
Процесс:
1) Читать данные в звонках. Читать кол-во записей где: тип – исходящий, продолжительность>30, CallDate >= startDate, CallDate < oneDay
2) Потоки:
- условный. Если Пункт 1 >= 30 - записываем в счетчик + 1. startDate и oneDay увеличиваем на 1 день и возвращаемся к пункту 1
- поток по умолчанию. startDate и oneDay увеличиваем на 1 день и возвращаемся к пункту 1
- условный. Если oneDay = endDate – завершить процесс

2. Кол-во рабочих дней.
Самый простой способ - посчитать кол-во дней в месяце и отнять кол-во дней, которые = суббота или воскресенье.
Достаточно базовых методов DateTime - https://msdn.microsoft.com/en-us/library/system.datetime(v=vs.110).aspx
Пример также можно найти в схеме CalendarUtilities (пакет Project).

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