Добрый день, господа.
Понимаю, что похожая тема неоднократно поднималась, но, видимо, изменения в версиях требуют уточнений.
Моя версия: Terrasoft XRM 3.3.2.43.

Надо: в ходе выполнения бизнес-процесса передать параметр AccountID из одной задачи в другую.

Сделал:

  1. 1. В диаграмме БП создал строковый параметр диаграммы AccounID.
  2. 2. В описание wa_TaskAction добавил строковый параметр элемента AccountID.
  3. 3. В диаграмме БП связал у задач параметр AccountID с соответствующим параметром диаграммы, у первой задачи указав его модификатор как "Входящий\Исходящий".

В коде скрипта wa_TaskActionScript параметр AccountID, насколько я понял, всё-таки сериализуется, поэтому дописывать там ничего не стал.

В итоге: значение контрагента не передается :(

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

Нравится

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

Сергей, Ваше замечание передано для анализа в департамент разработки продуктов.

Пока могу предложить обходное решение: в обработчике OnAfterExecute элемента БП написать код:

if (IsComplete) {
	WFSetParamValue(ActionItem.ParentItems.ParentDiagram, 'AccountID',
		ActionItem.Parameters('AccountID').Value);
}

Для работы данного решения достаточно только добавить в диаграмму параметр AccountID. Элемент "Задача" изменять нет необходимости.

Спасибо, Олег.

Сергей, добрый день.

Для решения проблемы попробуйте внести следующие изменения в функцию wa_TaskActionOnInitialize скрипта wa_TaskActionScript:

function wa_TaskActionOnInitialize(WorkflowAction, ActionItem) {
	WFConnectParams(ActionItem, 'AccountID', 'AccountID', pdtString, wpmitInOut);
	WFConnectParams(ActionItem, 'ContactID', 'ContactID', pdtString, wpmitInOut);
	/* MODULE OPPORTUNITIES */
	WFConnectParams(ActionItem, 'OpportunityID', 'OpportunityID', pdtString, wpmitInOut);
	/* ENDMODULE OPPORTUNITIES */
	WFConnectParams(ActionItem, 'ContractID', 'ContractID', pdtString, wpmitInOut);
	..............
	// аналогичные изменения для остальных параметров
}

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

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

Не стоит забывать о стандартном функционале, когда при создании нового контрагента и контакта идет проверка существования в системе таких сущностей по указанным в настройках полях (функционал проверки дублей в БД).

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

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

Террасофт 3.3

Нравится

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

Конечно, Вы можете на событие AfterPost (для примера) создавать все что угодно!

--
www.it-sfera.com.ua

var TaskDataset = Services.GetNewItemByUSI('ds_Task');
TaskDataset.Append();
TaskDataset('ID') = Connector.GenGUID();
TaskDataset('Title') = 'TestTask';
TasksDataset.Post();

ну и конечно же, подумайте насчет TaskDataset.DisableEvents();

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

Олег Лабьяк,
разработчик,
3-я линия Службы поддержки Terrasoft.

С технической стороны вовсе необязательно. Даже если поле является обязательным для заполнения(в датасете), то при создании вышеописанным методом поле можно не заполнять. Оно станет обязательным при открытии карточки данной задачи пользователем. Например, если скрипт не может определить приоритет данной задачи, то это сделает пользователь. Обязательными для заполнения являются обязательные на SQL сервере.

Но с логической точки зрения, Олег абсолютно прав:

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

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

Спасибо. Получилось :)

"Глова Сергей" написал:С технической стороны вовсе необязательно. Даже если поле является обязательным для заполнения(в датасете), то при создании вышеописанным методом поле можно не заполнять.

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

Насчет отключения событий. Я не сторонник такого отключения по следующим соображениям: если на датасет повешены обработчики некоторых событий, то предполагается, что данные обработчики должны обрабатываться именно для датасета (а не только в карточке, в которой он используется). Таким образом гарантируется опять же целостность данных в базе:

  • пересчет сумм в базовой валюте
  • расчет значений других объектов системы (например, расчет трудозатрат по проекту по выполненным задачам)
  • то же заполнение значений по-умолчанию

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

"Репко Артём" написал:Если поле обязательное, то для обеспечения целостности данных, в большинстве случаев его стоит объявлять обязательным как в датасете, так и в таблице. В базовой версии (конечно, смотря какой релиз) так и есть, поэтому вряд ли получится вышеописанный пример даже технически.

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

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

"Глова Сергей" написал:Но есть "логически" поля, которые обязательны только в определенном случае. Например, для типа клиент обязательно одно дополнительное поле, для типа поставщик - другое. И такие поля на целостность БД не влияют

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

"Глова Сергей" написал:Кстати, насколько я помню, наличие значений в обязательных полях проверял скрипт в конфигурации на кнопочку "Ок" (в ранних версиях), а не ядро на метод пост датасета.

Да, Вы правы. Если не заполнить поле, которое помечено как обязательное в таблице, произойдет банальный свал с выводом лога об ошибке СУБД.

Создал идею по обсуждаемой теме обязательных полей.

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

Доброе время суток!

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

Task4Group.avi (2,25 Мб)

Интересно? Пишите!

Нравится

Поделиться

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

Красиво :)

Nice :)
А после принятия задачи уже не видно, что изначально она была групповая?

Это же мелочи! :lol:
Скрытый атрибут есть - его можно вывести... Или представление сделать...

--
www.it-sfera.com.ua

Скажите, пожалуйста, а пользователи, которые находятся в группе, попадают на деталь "Команда" или как они видят эту задачу в расписании?

Здесь немного другая цель - задача формируется на группу, а один из пользователей группы принимает ее и становится ответственным. Только один - ее исполнитель. Есть отдельное представление "Не распределенные задачи"

--
www.it-sfera.com.ua

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

А в этом представлении пользователь видит только нераспределнные задачи групп, в которые он входит? Пользователи сознательно заходят туда за задачами? :)

"Раловец Ольга" написал:Пользователи сознательно заходят туда за задачами? :)

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

Данный функционал используется в БП.
Конкретно у нас - 2 заказчика:

1. Издательство, в БП "Продажа рекламы". Например, 2-3 корректора. По БП формируется задача на группу, а они сами принимают в работу. Это их бонусы! Начальник - контролирует. Человек поменялся, а группа та же и БП тот же!

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

Суть: возможность не персонифицированных задач - на абстрактную группу.

--
www.it-sfera.com.ua

"Раловец Ольга" написал:Пользователи сознательно заходят туда за задачами? :)
Это больше для контроля!
У пользователей есть напоминания + бонусы за выполненные задачи :lol:

--
www.it-sfera.com.ua

"Виталий Ковалишин aka samael" написал:Суть: возможность не персонифицированных задач - на абстрактную группу.

Таки интересно. Сталкивался с похожим примером в "Велика Кишеня" SD. У них там общий пул задач без ответственного, из которого инженеры забирают себе в работу по одной +категоризация задач +коэффициент сложности +еще какая-то фигня = денежка. У них просто всего одна группа ответственных :smile:

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

Спасибо за интересные комментарии :wink:

--
www.it-sfera.com.ua

В базовую версию :)

"Underscore a.k.a. _" написал:В базовую версию :)

Не думаю, что это столь типовая задача... хотя... :confused:

--
www.it-sfera.com.ua

У нас такая вещь была реализована одной из первых. Внешне выглядит также, но механизмы совсем другие. :) У нас не создаются несколько напоминаний, фильтры в напоминаниях и в разделе Задачи исправлены таким образом, чтобы отражались и персональные задачи и напоминания и групповые. При этом мы не блокируем установку напоминания "Ответственному". Так что можно поставить 3 разных напоминания: ответственному, группе и автору.
При этом получается задача одна, напоминание одно, естественно, что кто первый забрал, тот и забрал.
Группа формируется как простая группа в разделе "Контакты", так что технически в эту группу может входить любой Контакт.

Разные процессы - разные решения! :wink:

--
www.it-sfera.com.ua

Интересное решение, а можно получить инструкцию или готовое решение? )))
bashrus@bk.ru заранее спасибо.

Решение понравилось. Также интересует возможность получение инструкции. Или может в базовой версии уже реализовано нечто подобное?

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

Здравствуйте обитатели форума! Столкнулся я с такой проблемой, во время работы с разделом задача, при попытке сделать быстрый фильтр по задачам, а именно по заголовку задачи, система начинает ругаться и выдает в лог такое сообщение : (E) Ошибка выполнения метода 'dlTasksOnDatasetBeforeOpen'. 'null' is null or not an object «Call Stack», а дебагер ругается на следующую строчку : var TeamFilter = Filter.ItemsByCode('tcTeam');, иногда фильтрация проходит удачно и без ошибок, но при снятии и установлении флагов фильтрации задач по периоду (показать за период : сегодня, текущая неделя...) или при установлении/снятии флага фильтрации по ответственному выходит такая же ошибка ... Подскажите, это только у меня такое возникает, или все же есть не доработка?

Нравится

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

1. Какая версия сборки и на какой СУБД?
2. В разделе "Задачи" делались доработки или это базовая?

--
www.it-sfera.com.ua

Версия сборки 3.3.1, СУБД SQL 2005, раздел задач без доработок, базовый.

Если вы плюёте мне в спину, значит я впереди вас!

Только-что проверил на базовой TS XRM 3.3.1.45
не наблюдается описанная Вами проблема!

--
www.it-sfera.com.ua

Простите сборка 3.3.1.31

Если вы плюёте мне в спину, значит я впереди вас!

У меня есть только последняя 45... Возможно, в 31 и была какая-то проблема, но если конфигурация базовая - это Вам лучше на support писать! :smile:

--
www.it-sfera.com.ua

Спасибо! Обязательно так и сделаю. :smile:

Если вы плюёте мне в спину, значит я впереди вас!

если ошибка возникает хаотично то возможно нехватает этого кода

var Filter = BaseFilters.ItemsByCode('ContactIDs');
if (!Assigned(Filter)) {
Filter = BaseFilters.Items(0).ItemsByCode('ContactIDs');
}

var Parameters = Dataset.SelectQuery.Parameters;
var TeamFilter = Filter.ItemsByCode('tcTeam');

там присутствует код приведенный ниже, а переменная "Filter" уже существует, где мне сделать модификацию кода? Спасибо!
var IDs = GetContactsFilterArray();
SetAttribute(Self, 'ContactsFilterArray', IDs);
var Filter = Dataset.SelectQuery.Items(0).Filters.Items(0)
.ItemsByCode('ContactIDs');
var Parameters = Dataset.SelectQuery.Parameters;
var TeamFilter = Filter.ItemsByCode('tcTeam');
var SubSelectFilter = TeamFilter.TestExpression
.ExpressionSelectQuery.Items(0).Filters;
var OwnerIDsFilter = Filter.ItemsByCode('tcOwnerIDs');
var ContactIDsFilter = Filter.ItemsByCode('tcContactIDs');
var SubContactIDsFilter = SubSelectFilter.ItemsByCode('tcContactIDs');
ApplyIncludeFilter(OwnerIDsFilter, IDs, true, null, Parameters);
ApplyIncludeFilter(ContactIDsFilter, IDs, true, null, Parameters);
ApplyIncludeFilter(SubContactIDsFilter, IDs, true, null, Parameters);
TeamFilter.IsEnabled = true;
Filter.IsEnabled = true;

Если вы плюёте мне в спину, значит я впереди вас!

var IDs = GetContactsFilterArray();
SetAttribute(Self, 'ContactsFilterArray', IDs);
var Filter = Dataset.SelectQuery.Items(0).Filters.Items(0)
.ItemsByCode('ContactIDs');
if (!Assigned(Filter)) {
Filter = Dataset.SelectQuery.Items(0).Filters.Items(0).Items(0).ItemsByCode('ContactIDs');
}

var Parameters = Dataset.SelectQuery.Parameters;
var TeamFilter = Filter.ItemsByCode('tcTeam');
var SubSelectFilter = TeamFilter.TestExpression
.ExpressionSelectQuery.Items(0).Filters;
var OwnerIDsFilter = Filter.ItemsByCode('tcOwnerIDs');
var ContactIDsFilter = Filter.ItemsByCode('tcContactIDs');
var SubContactIDsFilter = SubSelectFilter.ItemsByCode('tcContactIDs');
ApplyIncludeFilter(OwnerIDsFilter, IDs, true, null, Parameters);
ApplyIncludeFilter(ContactIDsFilter, IDs, true, null, Parameters);
ApplyIncludeFilter(SubContactIDsFilter, IDs, true, null, Parameters);
TeamFilter.IsEnabled = true;
Filter.IsEnabled = true;

Спасибо огромное! Теперь все заработала как надо :)

Если вы плюёте мне в спину, значит я впереди вас!

Разработчики написали код... Вы его установили... А потом, кто-то подумал о значение null... Добавили заплатку... А Вам уж, звиняйте, нужно ручками дописывать :biggrin:

--
www.it-sfera.com.ua

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

Буквально два дня назад у одного и только одного пользователя в системе переставли открываться сервисы Задачи, Контрагенты и Контакты.

При попытке открыть эту закладку появляется сообщение об ошибке:

Ошибка открытия источника данных "ds_Account"
Оригинальное сообщение об ошибке: Dynamic SQL Error
SQL error code=-204
Table unknown
vw_Account
At line 14, column 15
can't format message 13:796 -- message file C:\Program Files\Terrasoft CRM X25\firebird.msg not fount
Error Code: 249

Аналогично для источников ds_Contacts и ds_Task.

Пробовал в администрировании сбрасывать и заново устанавливать права доступа, ситуация не меняется. Остальные сервисы работают нормально. То есть открываем Проекты, там все показывает, кроме Клиента и Контакта.

Нравится

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

Может попробовать забрать и снова раздать права на эти разделы.

Здравствуйте, Алексей!
Для решения возникшей у Вас проблемы могу посоветовать зайти в TSAdmin.exe, открыть таблицу, например, tbl_Account и пересохранить ее (для этого добавьте в название таблицы например пробел, потом уберите его и сохраните таблицу). Таблица пересохранится, что в результате приведет к пересозданию View-представления vw_Account на сервере.
Аналогичные действия выполните для таблиц tbl_Contacts и tbl_Task.
После этого перезапустите рабочее приложение Terrasoft CRM и протестируйте работосопосбность системы.

Также советую скопировать файл Firebird.msg из папки Firebird (с серверной машины) на клиенскую машину. Таким образом, на клиентской машине должны быть два файла fbclient.dll и Firebird.msg.

Желаю удачи!

Мельникова Екатерина

При попытке пересохранить tbl_Account получил вот это сообщение об ошибке.

violation of FOREIGN KEY constraint "PCONTACT_ID" on table "tbl_Contact"
Foreign key reference target does not exist
violation of FOREIGN KEY constraint ""
Error Code: 146
ALTER TABLE "tbl_Account" ADD CONSTRAINT "FAccountPrimaryContactID2"
FOREIGN KEY ("PrimaryContactID") REFERENCES "tbl_Contact" ("ID")

Проверил отношения, все заполнено верно. Поле ID в tbl_Contact присутствует. Странно...

При пересохранении tbl_Task получил вот это сообщение:

violation of FOREIGN KEY constraint "PCONTACTGROUP_ID" on table "tbl_ContactGroup"
Foreign key reference target does not exist
violation of FOREIGN KEY constraint ""
Error Code: 146
ALTER TABLE "tbl_Task" ADD CONSTRAINT "FTaskOwnerGroupID"
FOREIGN KEY ("OwnerGroupID") REFERENCES "tbl_ContactGroup" ("ID")

Тоже все проверил, все должно быть в норме.

tbl_Contact пересохраняется нормально. И кстати, этот сервис у пользователя заработал еще до того, как е его пере сохранил.

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

Горелов Виталий
Компания Лабитек

Да, совершенно верно. Были ошибки в ссылках на таблицы. Исправил, сервисы пересохранил. Как только появится возможность, я тут же проверю заработали ли сервисы у пользователя.

После исправления ошибок в ссылках, таблицы пересохранились нормально. Но система ведется себя странно. Пользователь входит, сообщений об ошибках нет, но все датасеты пустые и наверху в заголовке окна террасофта, где пишется в скобках ФИО контакта - Террасофт 3.1 - Террасофт (Иванов Иван Иванович) - теперь в скобках пишет "Null".
То есть теперь заголовок окна выглядит так:

Террасофт 3.1 - Террасофт (Null)

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

:-) Террасофт 3.1 - Террасофт (Null)
значит пользователь не имеет прав доступа на строку своего контакта (в разделе Администрирование , пользователь создается с привязкой к определённому контакту) , дайте ему права на чтение этой строки

Так в том-то и дело, что в Администрировании в Террасофт у пользователя стоят все галочки на группе таблиц Контакты. И конкретно на этот контакт в Детали "Доступ" указанному пользователю разрешено Запись и Чтение.

"Барабанов Алексей Александрович" написал:Так в том-то и дело, что в Администрировании ...

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

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

Здравствуйте. У меня CRM X15 версии 3.2.0.11 стандартной конфигурации. Стоят следующии задачи:
1) при создании новой задачи автоматически запускать таймер (аналогично "действия->запустить таймер", только делать это программно).
2) при закрытии задачи сделать обязательным поле "подробный результат". То есть чтобы пользователь не мог закрыть задачу, не заполнив это поле.
Как мне это сделать? Заранее большое спасибо за помощь!

Нравится

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

1)var Timer = System.CreateObject('TSWindowLibrary.Timer');
зачем его создавать , я понять немогу
2) в окне редактирования задач , на событии OnDatasetDataChange

function dlDataOnDatasetDataChange(DataField) {
if (!Assigned(DataField)) {
return;
}
var DataFieldName = DataField.Name;
if (DataFieldName == 'StatusID'){
if (DataField.Value == 'айдишник состояния выполнено' ){
dlData.Dataset.DataFields('ResultID').IsRequired = true;
} else {
dlData.Dataset.DataFields('ResultID').IsRequired = false;
}

}
}

Вместо последнего if я бы написал

dlData.Dataset.DataFields('ResultID').IsRequired = (DataField.Value == 'айдишник состояния выполнено');

Спасибо, со 2-м пунктом разобрался, а вот с первым нет. Имелось ввиду что менеджеры, когда создают задачу (чаще всего они создают ее себе сами) часто забывают запутить таймер ее выполнения со всеми вытекающими отсюда последствиями.
Руководитель отдела попросил меня, чтобы это делалось автоматически, т.к. в 90% случаев факт того, что менеджер завел задачу ознает что он уже начал ее выполнять, то есть логично было бы запускать его автоматически, а не совершать дополнительное ручное действие.

Заранее спасибо за помощь!

можно попробовать изменить под себя функцию StartTimer()
которая находится в scr_TasksWorkspace
но она может неработать для вновь созданых задачь

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