Добрый день!

есть ли возможность обратиться к BpmOnline из клиентской части стороннего приложения?

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

можно ли вызвать DataService из js стороннего приложения?

если можно, то где можно посмотреть примеры

если я правильно понимаю, то можно работать при помощи oData из js стороннего приложения, но примеров тоже не нашла. 

 

 

Нравится

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

Добрый день

Из клиентского приложения можно легко работать с DataService. Для этого нужно:

1. Авторизоваться в bpmonline

2. Отправлять данные

Здесь есть описание по авторизации https://academy.terrasoft.ua/documents/technic-sdk/7-12/integraciya-s-sistemoy-i-vneshniy-api

С клиентской стороны вы можете организовать "общение" c помощью ajax или XmlHttpRequest

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

https://www.html5rocks.com/en/tutorials/cors/

https://stackoverflow.com/questions/298745/how-do-i-send-a-cross-domain-post-request-via-javascript

год назад писали, что это невозможно

https://community.terrasoft.ru/questions/cors-i-avtorizacia-iz-klientsk…

получается, теперь эта возможность доступна?

у вас нет примера подключения, пока возникают сложности с подключением

Коллеги, кто сталкивался с подобной проблемой?

В конфиг сайта добавил <httpProtocol>

      <customHeaders>

        <add name="X-Frame-Options" value="SAMEORIGIN" />

<add name="Access-Control-Allow-Origin" value="*" />

<add name="Access-Control-Allow-Methods" value="GET, PUT, POST, DELETE, OPTIONS" />

<add name="Access-Control-Allow-Credentials" value="true" />

<add name="Access-Control-Allow-Headers" value="X-PINGOTHER, Origin, Cache-Control, Content-Type, Authorization, X-Requested-With, Accept" />

      </customHeaders>

    </httpProtocol>

 

С помощью JS отправляю запрос

$.ajax({
   url: serviceUrl + 'ContactCollection',
   headers: {
      'Content-Type': 'application/json;odata=verbose',
      'Authorization': 'Basic ' + btoa('Юзер:Пароль')
   },
   dataType: "json",
   data:  JSON.stringify({"Name": "123"}),
   method: 'POST'
});

Возвращается 401 ошибка, права Юзер в права доступ на операции к OData предоставил, в объекте Contact к OData также дал. Запросы кросс-доменные. в чем проблема?

Евгений Волоцкой,

Евгений, если зайти под пользователем в систему, он может перейти в раздел контакты? 

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



Коллеги, добрый вечер!

Подскажите пожалуйста, в каком модуле происходит расчет поля "Итого" раздела "Заказы"?

Всё обыскал, никак не найду, в подсказке написано, что считается автоматически как сумма всех "Итого" на детали "Продукты", но самих расчетов ни в OrderPageV2, ни в OrderProductDetailV2, ни в OrderProductPageV2, ни в импортируемых ими модулях не вижу. Есть место с запросом значения из базы, но как оно туда попадает изначально неясно.

Нравится

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

Смотрите объект OrderProduct, а там процессы:



Владимир, спасибо.

Тагиз, также можете обратить внимание на OrderAmountHelper

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

Здравствуйте. Добавила в раздел быстрые фильтры по дате и отвественному, А они не отображаются.

ниже код добавления

define("UsrTSiPOSection", ["BaseFiltersGenerateModule"], function(BaseFiltersGenerateModule) {

    return {

        entitySchemaName: "UsrTSiPO",

        methods: {

            // Инициализирует фиксированные фильтры.

            initFixedFiltersConfig: function() {

                // Создание конфигурационного объекта.

                var fixedFilterConfig = {

                    // В качестве схемы объекта для фиксированных фильтров указывается схема объекта раздела.

                    entitySchema: this.entitySchemaName,

                    // Массив фильтров.

                    filters: [

                        // Фильтр периода.

                        {

                            // Название фильтра.

                            name: "PeriodFilter",

                            // Заголовок фильтра.

                            caption: this.get("Resources.locatizableStrings.PeriodFilterCaption"),

                            // Тип данных — дата.

                            dataValueType: this.Terrasoft.DataValueType.DATE,

                            columnName: "Date",

                            // Дата начала периода фильтрации.

                            startDate: {

                                // Фильтруются данные из колонки [Date].

                                //columnName: "StartDate",

                                // Значение по умолчанию — начало текущей недели.

                                defValue: this.Terrasoft.startOfWeek(new Date())

                            },

                            // Дата завершения периода фильтрации — завершение текущей недели.

                            dueDate: {

                                //columnName: "DueDate",

                                defValue: this.Terrasoft.endOfWeek(new Date())

                            }

                        },

                        // Фильтр ответственного.

                        {

                            // Название фильтра.

                            name: "Owner",

                            // Заголовок фильтра.

                            caption: this.get("Resources.locatizableStrings.OwnerFilterCaption"),

                            // Фильтрация данных из колонки [Owner].

                            columnName: "Owner",

                            // Значение по умолчанию — контакт текущего пользователя.

                            // Берется из системной настройки.

                            defValue: this.Terrasoft.SysValue.CURRENT_USER_CONTACT,

                            // Тип данных — справочник.

                            dataValueType: this.Terrasoft.DataValueType.LOOKUP,

                            // Фильтр.

                            filter: BaseFiltersGenerateModule.OwnerFilter

                        }

                    ]

                };

                // Атрибуту [FixedFilterConfig] присваивается ссылка на созданный конфигурационный объект.

                this.set("FixedFilterConfig", fixedFilterConfig);

            }

        }

    };

});

Нравится

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

В Вашем пользовательском разделе существуют поля с названиями 

"Owner", "Date"?

Например в этом месте -  columnName: "Owner", скорее должно быть  columnName: "UsrOwner", или как вы там назвали поле с ответственным. С датой то же самое. Надеюсь, что это поможет.

Alex Zaslavsky, изменила названия, но фильтры все равно не отображаются

Никульшина Алёна,

entitySchema: this.entitySchemaName, - здесь удалите Name

напишите просто - entitySchema: this.entitySchema,

Никульшина Алёна, работает? Или фильтры все еще не отображаются?

Alex Zaslavsky,

 Да , спасибо большое.все отображается

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

Добрый день

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

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

Кто создаёт - Все сотрудники компании, кому дано право - системные администраторы.

Сотрудники находятся в разных орг. ролях (согласно региональному делению) но присутствуют в орг роли Все сотрудники компании.

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

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

И какой бп построить, чтобы отнять это право на существующие записи

Нравится

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

Добрый день, Иван.

 

Чтобы забрать права у "Ответственного" Вам необходимо очистить поле "Ответственный" в замещающем объекте: https://prnt.sc/j3olvl



Для изменения прав на существующие записи можете воспользоваться приложением с Маркетплейс: Мастер настройки прав доступа

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

Добрый день.

В системе bpmonline на странице контрагента есть вкладка "Контакты и структура". На этой вкладке есть информация "Контакты контрагента". Судя по документации в этой детали отображаются "... контакты, у которых данная компания в указана качестве текущего места работы на детали [Карьера] или в профиле". Скажите, а где можно посмотреть на программный код, который связывает контрагента с контактами (карьерой контактов) для формирования списка этой детали? Вопрос связан с тем, что есть намерение повторить эту связь для получения аналогичного списка для контрагента в своем бизнес-процессе. Просматривая существующие схемы конфигурации я, к сожалению, не нашел нужного. Заранее спасибо за ответ.

Нравится

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

Непонятно, что требуется получить на выходе. Разве нельзя просто через esq в бизнес-процессе получить нужные данные?

Кузнецов Сергей,

Хочется в esq повторить логику запроса к данным, который выполняет деталь "Контракты контрагента". Можно ориентироваться на приведенное описание из документации, а можно посмотреть на существующий код и повторить запрос. Также просто хочется разобраться как организована эта деталь.

Игорь Козлитин,

В детали AccountContactsDetailV2 используется фильтрация _getContactCareerFilter, которая фильтрует контакты в соответствии с его местом работы, т.е. Контрагентом:

AccountContacts: {

schemaName: "AccountContactsDetailV2",

filter: {

masterColumn: "Id",

detailColumn: "Account"

},

useRelationship: true,

filterMethod: "_getContactCareerFilter"

}



Посмотреть реализацию данного фильтра Вы можете в схеме AccountPageV2 пакета UIv2, выполнив поиск по словосочетанию "getContactCareerFilter"

Анна Журавель,

 Большое спасибо. Ваш ответ очень помог.

Да, по сути логика простая. Всего лишь один единственный фильтр, должен совпадать контрагент. Деталь построена прямо на объекте "Контакт". Т.е. делаем выборку по объекту Контакт, где контрагент равен конкретному.

Кузнецов Сергей,

Дополню Ваш ответ - там еще сущность "Карьера контакта" учитывается.

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

Добрый день!



Вроде, хотелось сделать совершенно стандартную вещь, но не пошло по стандарту:



необходимо в объекте Contact отлавливать изменение поля MobilePhone на сигнал ContactSaving.



Для этого по сигналу написали скрипт:



    var newMobilePhone = Entity.GetTypedColumnValue("MobilePhone");

    var oldMobilePhone = Entity.GetTypedOldColumnValue("MobilePhone");


    throw new Exception(newMobilePhone + " " + oldMobilePhone);

    return true;



Однако обе переменных newMobilePhone и oldMobilePhone  всегда принимают старое одинаковое значение.



Как получить актуальное новое значение этого поля?

Нравится

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

Добрый день, Владимир!

Все работает верно, поскольку Вы используете сигнал ContactSaving, то старое и новое значение это одно и тоже значение, поскольку транзакция еще не прошла. 

Если же использовать сигнал ContactSaved, то новое и старое значения будут разными.

 

В пакете Base вижу такой код на событие ContactSaving:



IsCurrentUserPhoroChanged = (Entity.GetTypedColumnValue<Guid>("PhotoId") !=

    Entity.GetTypedOldColumnValue<Guid>("PhotoId") && Entity.GetTypedColumnValue<Guid>("Id") ==

UserConnection.CurrentUser.ContactId);



И во многих других местах на Saving происходит проверка изменения поля как раз таким способом

Владимир Соколов,

Действительно, если взять и выполнить аналогичный пример для поля Name, то в результате получим сообщение с разными именами:

var newName = Entity.GetTypedColumnValue&lt;string&gt;("Name");
var oldName = Entity.GetTypedOldColumnValue&lt;string&gt;("Name");throw new Exception(newName + " " + oldName );

Решила посмотреть что происходит на самом деле, изменила поле Name и поле MobilePhone и отловила запросы профайлером и получила следующее

изначально происходит изменения имени, 

после изменяется телефон в таблице ContactCommunication, 

и только потом изменяться телефон в контакте. 

И потому, на этапе Saving значения старое и  новое одинаковые, поскольку изменения телефона происходит в рамках процесcа ContactSaved (пакет Base).

с ContactSaved получается еще интереснее...

Во-первых, когда сообщение выдается, то оба номера (старый и новый) идентичны

А во-вторых, теперь это сообщение выдается далеко не на каждое сохранение, то есть, ощущение, что ContactSaved срабатывает не всегда

Владимир Соколов,

Вы можете перейти в конфигурации в к процессу на объекте Contact пакета Base, и ознакомиться с логикой ContactSaved. 

Поле MobilePhone изменяется не в рамках сохранения контакта, а в рамках метода SynchronizeCommunication(), который вызывается после сохранения контакта.

Ещё довольно странное поведение из-за такой синхронизации. В бизнес-процессе совсем не отлавливается событие изменения поля MobilePhone. 

С другой стороны, количество Communication options с таким типом может быть больше 1, потому непонятно, какое из них синхронизировано с главным полем в карточке, и изменение какого из них отслеживать

 

 

Добрый день, 

Стартовый сигнал действительно не реагирует на изменение в контакте/контрагенте полей Email/Мобильный телефон. Это связано с базовой логикой синхронизации этих полей с деталью средства связи контакта/контрагента. Вы можете ознакомиться с логикой в конфигурации, если открыть процесс элемента Contact и ContactCommunication.

Для решения задачи можно создать дополнительный процесс, который будет срабатывать при добавлении/изменении записи непосредственно в объекте [Средство связи контакта/контрагента].

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

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

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

Нравится

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

Александр, здравствуйте!

Данная проблема в работе с печатными формами может возникать из-за дополнения Marketplace MS Word printables setup wizard (наблюдается в версиях приложения 7.11.0+). Мы передали разработчику дополнения информацию для внесения правок в работу данного дополнения. На данный момент рекомендуем удалить данное дополнение, чтоб иметь возможность работать с печатными формами в MS Word.

Если у Вас отсутствует данное дополнение, напишите нам на support@terrasoft.ru, опишите, пожалуйста, проблему и предоставьте временный доступ к Вашему сайту для более детального анализа.

Одеяненко Юлия, сегодня зарегистрировал бандл на 14 дней, чтобы сделать печатную форму. Итог - пустое окно. Если честно, то работает через пень-колоду. До этого тоже то работало, то опять такая ситуация случалась. Что делать то?

Если тоже установлено вышеупомянутое дополнение «MS Word printables setup wizard», то лучше уточнить у его автора.

Зверев Александр, установлен только плагин - https://academy.terrasoft.ru/documents/studio/7-12/ustanovka-plagina-bp… и всё

Видимо, на демке нет ни одной печатной формы типа Word, их нужно создавать в соответствующем справочнике:

Вообще, плагин выполняет вспомогательную роль для быстрого выбора названий полей. Настраивать печатные формы можно в Word и без него, меняя поля вручную, а затем залив изменённый шаблон в справочник.

Разобрался, такое происходит, если истекла подписка в Word.

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

На демке всё есть, из-за подписки, проверил с коллегой данную версию - у него быстро всё подключилось. Такой вопрос - что выполняет макрос в Word-е? Кроме закавычивания соответствующих полей он делает какие-то пометки на выводимом поле? Какие-то ссылки добавляет к объекту, либо что-то другое?

Думаю, плагин меняет только word-файл, на стороне bpm'online ничего не трогает. А вся логика замены макросов на нужные значения полей сделана в системе в С#-схеме WordReportUtility.

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

В какой то момент пропали настройки журнала изменений по контакту.

Как можно отследить изменение настроек аудита? Кто, когда?

Нравится

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

Егор, добрый день!

Обычно такие задачи решаются с помощью самого журнала аудита (не журнала изменений). Но сейчас в системе не логируется изменение настроек журнала изменений (я создала соответствующую идею в беклоге профильной команды). Список логируемых операций можно посмотреть тут: https://academy.terrasoft.ru/documents/studio/7-12/razdel-zhurnal-audita

В качестве обходного решения можно сделать следуюшее:

1. Для анализа текущей ситуации проанализировать логи приложения (там должны быть видны соответсвующие запросы) и сравнить с данными по сессиям пользователей.

2. На будущее реализовать собственный тригер на уровне БД, который будет писать в лог, если кто-то будет менять настройки журнала изменений.

Старун Юлия,

спасибо за развернутый ответ!

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

Настройка - по каким полям ведется логирование в таблицу SysContactLog.

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

        {
          "UId": "736c30a7-c0ec-4fa9-b034-2552b319b633",
          "Name": "Name",
          "CreatedInSchemaUId": "11ab4bcb-9b23-4b6d-9c86-520fae925d75",
          "ModifiedInSchemaUId": "4cbdc6f3-625d-4639-92bf-bb19d4c9d58e",
          "CreatedInPackageId": "66e9e705-64b4-4dda-925e-d1e05a389eb6",
          "DataValueTypeUId": "ddb3a1ee-07e8-4d62-b7a9-d0e618b00fbd",
          "RequirementType": 1,
          "IsTrackChangesInDB": true,
          "IsLocalizable": true
        },

Но вот на уровне базы данных это уже хранится в колонке MetaData таблицы SysSchema в не таком удобном виде. Там следует искать код Е16, чтобы понять, колонка с каким UID логируется:

Таким образом, триггер нужно вешать на таблицу SysSchema на колонку MetaData по тому объекту, который вы хотите отследить. И сохранять весь текст метаданных, а потом уже анализировать его вручную. Наверное, можно даже посмотреть, какой запрос отправляет система в БД при открытии страницы настроек журнала изменений - там наверняка есть встроенные механизмы парсинга этих данных.

В общем я постараюсь повысить приоритет реализации логирования этих изменений через журнал аудита средствами системы :)

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

Периодически в логе возникает следующего вида ошибка

2018-04-09 08:54:58,222 [62] ERROR CP-BPM\bpmadmin Terrasoft.Core.Process.ProcessEngineImpl GetIsMatchCondition - (null)
System.FormatException: Идентификатор GUID должен содержать 32 цифры и 4 дефиса (xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx).
   в System.Guid.GuidResult.SetFailure(ParseFailureKind failure, String failureMessageID, Object failureMessageFormatArgument, String failureArgumentName, Exception innerException)
   в System.Guid.TryParseGuidWithNoStyle(String guidString, GuidResult& result)
   в System.Guid.TryParseGuid(String g, GuidStyles flags, GuidResult& result)
   в System.Guid..ctor(String g)
   в Terrasoft.Common.DataTypeUtilities.ValueAsType[TResult](Object value)
   в Terrasoft.Nui.ServiceModel.DataContract.Parameter.GetValue(UserConnection userConnection, DataValueType forcedDataValueType, Boolean useUtcTime)
   в Terrasoft.Nui.ServiceModel.Extensions.QueryExtension.EsqBuilder.CreateExpression(BaseExpression expression, Boolean useUtcTime)
   в Terrasoft.Nui.ServiceModel.Extensions.QueryExtension.EsqBuilder.CreateCompareFilter(Filter filterConfig)
   в Terrasoft.Nui.ServiceModel.Extensions.QueryExtension.EsqBuilder.CreateFilter(Filter filterConfig)
   в Terrasoft.Nui.ServiceModel.Extensions.QueryExtension.EsqBuilder.CreateFilterGroupFilter(Filter filterConfig)
   в Terrasoft.Nui.ServiceModel.Extensions.QueryExtension.EsqBuilder.CreateFilter(Filter filterConfig)
   в Terrasoft.Nui.ServiceModel.Extensions.QueryExtension.EsqBuilder.AddQueryFilters(EntitySchemaQuery currentEsq, Filters filterConfigs)
   в Terrasoft.Nui.ServiceModel.Extensions.QueryExtension.EsqBuilder.CreateExpression(BaseExpression expression, Boolean useUtcTime)
   в Terrasoft.Nui.ServiceModel.Extensions.QueryExtension.EsqBuilder.CreateCompareFilter(Filter filterConfig)
   в Terrasoft.Nui.ServiceModel.Extensions.QueryExtension.EsqBuilder.CreateFilter(Filter filterConfig)
   в Terrasoft.Nui.ServiceModel.Extensions.QueryExtension.EsqBuilder.CreateFilterGroupFilter(Filter filterConfig)
   в Terrasoft.Nui.ServiceModel.Extensions.QueryExtension.EsqBuilder.CreateFilter(Filter filterConfig)
   в Terrasoft.Nui.ServiceModel.DataContract.ProcessDataContractFilterConverter.ConvertToEntitySchemaQueryFilterItem(EntitySchemaQuery esq, String serializedFilters)
   в Terrasoft.Core.Process.ProcessEngineImpl.GetIsMatchCondition(UserConnection userConnection, Entity entity, String conditionData)

Никак не могу понять кто ее туда пишет. Есть способ?

Нравится

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

Добрый день

Судя по callstack'у это ошибка при работе процесса. Посмотрите процессы, которые выполнялись в это время.

А так просто по данной записи сложно сказать. Не ясно, она возникает и что-то не работает (что?). Она выскакивает на клиенте  (какие действия совершаются, что во вкладке Network?). Выполнение процесса прервалось (на каком-то элементе?) и т.д.

Артем Гура,

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

Алексей-Карягин,

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

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

Добрый день.

Настроил в профиле пользователя синхронизацию с почтовым ящиком.

Прикрепил данные таблицы MailboxSyncSettings к пакету.

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

На отправку email всё работает.

Нравится

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

Здравствуйте, Игорь!

Перенести настройки почтовых ящиков через привязку к пакету не получится. При добавлении почтового ящика происходит вычитка папок и добавления их в таблицы MailboxFoldersCorrespondence, ActivityFolder и другие. Также происходит раздача необходимых прав и добавление триггеров синхронизации.

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