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

Добрый день!
в BPM есть возможность сделать поле обязательным по какому-то условию
с помощью BINDPARAMETER

по правилу
rules: {
"Fieldname": {
BindParameterRequiredAccountByType: {
ruleType: BusinessRuleModule.enums.RuleType.BINDPARAMETER,
property: BusinessRuleModule.enums.Property.REQUIRED,

conditions: [{
// Выражение левой части условия.
leftExpression: {
type:
attribute:
attributePath:
},
comparisonType: Terrasoft.ComparisonType.NOTEQUAL,
rightExpression: {
type: ,
value:
}
}]
}
}

Скажите, пожалуйста, если я хочу, чтобы условие было следующим
Terrasoft.CurrentUser.userType != Terrasoft.UserType.SSP
( т.е. текущий пользователь не является пользователем веб-портала)

то что я должна написать в левой части условия и в правой?
что необходимо указывать в type, attribute, attributePath
для Terrasoft.CurrentUser.userType
type в этом случае BusinessRuleModule.enums.ValueType.CONSTANT?
а что тогда attribute, attributepath?

правая часть выражения Terrasoft.UserType.SSP в этом случае как должна выглядеть?
type тоже в этом случае BusinessRuleModule.enums.ValueType.CONSTANT,
а value это Terrasoft.UserType.SSP ?

P.S. в каком пакете сейчас находится модуль BusinessRuleModule? где можно его посмотреть?(версия 7.6)

Нравится

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

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

Для решения задачи рекомендуем ознакомится со статьей “Как сделать поле обязательным для заполнения по определенному условию”
http://academy.terrasoft.ru/documents/docs/technic/SDK/7.6.0/RequiredFi…

В версии 7.6 схема BusinessRuleModule находится в пакете NUI.

Добрый день! Спасибо, я эту статью читала.
Там в примере - Правило зависимости обязательности поля [Контрагент] от значения в поле [Тип].
там понятно, что указывать в левой и в правой части условия.
мне не понятно, как должна выглядеть левая часть условия в данном выражении,
если левая часть условия - это Terrasoft.CurrentUser.userType

Какой тип выражения должен быть в данном случае?
Возможные значения: ATTRIBUTE, CONSTANT, SYSSETTING, SYSVALUE, CARDSTATE
Тип текущего пользователя - это же не аттрибут модели представления и не константа, не
системная настройка, не системное значение и не состояние карточки.
Тогда что это? какое значения для type выбрать в этом случае?

Дарья, добрый день!

Если бы необходимо было использовать в сравнении значение Terrasoft.CurrentUser - тип выражения должен быть SYSVALUE. Но в Вашем случае можно использовать следующий подход:

1) для правого выражения указать тип CONSTANT и значение Terrasoft.UserType.SSP;
2) создать в блоке attributes атрибут

"CurrentUserType": {
	dataValueType: Terrasoft.DataValueType.TEXT,
	value: Terrasoft.CurrentUser.userType 
}

3) для левого выражения указать тип ATTRIBUTE и атрибут CurrentUserType.

Показать все комментарии
sales
лендинги
7.x

Возможно ли в Sales Commerce 7.6 настроить лендинги с сайта?

Нравится

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

В базовой версии продукта Sales 7.6 уже реализован данный функционал и присутствует раздел Лендинги.
Он не вынесен в базовое рабочее место "Продажи". Вынести его туда Вы можете в Настройке рабочих мест.

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

Есть деталь на странице проекта. В lookupListConfig справочного поля Проект указаны два поля, которые доступны при добавлении или изменении записи детали, но не доступны при копировании. Можно скопировать запись, сохранить ее, а потом изменить - поля становятся доступными. Поля детали расчитываются на основе полей на странице проекта. Возможно каким-то образом сделать их доступными, чтобы не брать значения с помощью EntitySchemaQuery?

Нравится

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

Добрый день, Олег.

Если Вам не трудно, прошу Вас уточнить Ваш вопрос скриншотами.

Если я правильно понял, то Вас интересует как передать значение со страницы проекта в страницу детали, чтобы рассчитать значение полей. Это можно сделать с помощью messages.
1. В объект messages проекта добавить SUBSCRIBE. В объект messages детали добавить PUBLISH.
2. На init проекта подписаться на сообщение
this.sandbox.subscribe("GetSomeInfoFromDetail", function(argument) {
return this.someFunctionUsingArgument();
}, this, ["key"]);
3. На детали, когда Вам нужно получить значение с проекта сделать sandbox.publish
var result = this.sandbox.publish("GetSomeInfoFromDetail", valueToSend, ["key"]);

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

Спасибо, Вы очень помогли :smile:

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

Добрый день!
В разделе Обращения в ITIL есть деталь Активности.
На данной детали при нажатии на кнопку Добавить появляется
выпадающий список: "Добавить задачу" или "E-mail"

Подскажите, пожалуйста, в какой схеме какого пакета реализован вызов данного выпадающего списка.
В схеме CaseActivityDetail не нашла подобного функционала.

Спасибо

Нравится

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

Добрый день!

Дарья, сам механизм находится в схеме BaseGridDetailV2, но Вы не сможете вносить туда модификации, да и не надо, в принципе.
Вы можете воспользоваться стандартными средствами работы СРМ: откройте мастер раздела "Активности", добавьте новую карточку редактирования для нужного типа, сделайте дизайн карточки, сохраните, выполните команду flushall в командной строке Redis Client. Предварительно внесите тип в справочник "Типы активности".
Этих действий достаточно.

Добрый день!
Но я не планировала делать новую карточку редактирования для нужного типа )
Я бы хотела внести изменения в начальные значения для существующего типа e-mail
При нажатии на действие "e-mail" в детали Активности в разделе Обращения хотела бы? чтобы в поле "Кому" подставлялся определенный адрес ( не конкретный адрес, а зависящий от данных в обращении).
Возможно ли такое?
В связи с этим и спрашивала, где находится вызов этих действий, чтобы найти далее какая карточка вызывается при нажатии на действие e-mail

Извините, не понял саму суть задачи. Что значит "чтобы в поле "Кому" подставлялся определенный адрес"?
Там байндинг происходит автоматически на открытие карточек AddTypedRecordButton => values => menu => items = >

"bindTo": "EditPages

".

		AddTypedRecordButton
				{
					"operation": "insert",
					"name": "AddTypedRecordButton",
					"parentName": "Detail",
					"propertyName": "tools",
					"values": {
						"itemType": Terrasoft.ViewItemType.BUTTON,
						"menu": {
							"items": {
								"bindTo": "EditPages"
							}
						},
						"visible": {"bindTo": "getAddTypedRecordButtonVisible"},
						"enabled": {"bindTo": "getAddTypedRecordButtonEnabled"},
						"style": Terrasoft.controls.ButtonEnums.style.TRANSPARENT,
						"caption": {"bindTo": "Resources.Strings.AddButtonCaption"}
					}
				},

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

Добрый вечер!
Спасибо, я в принципе, получила ответ на свой вопрос.
При нажатии на действие "Email" вызывается обычная карточка ActivityPage, но только типизированная с типом e-mail
соответственно, те изменения, которые я хочу произвести ( заполнение некоторых значений по-умолчанию при нажатии на "email" в детали) необходимо делать в схеме CaseActivityDetail.
Просто я почему-то предположила, что здесь какая-то другая схема для e-mai участвует, и пыталась ее найти, но оказывается схема та же самая CaseActivityDetail

Спасибо

Кстати, вопрос как раз по теме - каким образом оттуда удалить лишний пункт? Дело в том, что при переезде с облачной версии на серверную система заново создала типы контрагента Конкурент, и он задвоился в этом выпадающем списке. Справочник типов-то мы вычистили, а вот этот пункт остался ..

Здравствуйте, Антон!

Судя по описанию задачи необходимо удалить дублирующийся пункт “Конкурент” кнопки добавить в разделе Контрагенты. В таком случае следует удалить ненужные дубли в базе данных в таблицах : SysMuduleEdit, SysMuduleEditLcz. Предварительно рекомендуем сделать копию базы данных.

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

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

Нравится

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

Добрый день, Никита.

Скиньте, пожалуйста, скриншот того, как Вы добавляете объекты в свой раздел и как они располагаются друг под другом.

Если я правильно понял, то Вы имеете в виду объекты: реестр, расписание и карта. Если это те объекты, о которых речь, то их позиционирование регламентируется CSS стилями. Подробнее о расположении элементов в строку с помощью CSS можно почитать тут:
http://htmlbook.ru/samlayout/blochnaya-verstka/strochno-blochnye-elemen…
И по запросу в Google:
css div расположение элементов в строку

"E.Podkovka" написал:

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


Действительно, добавил свой модуль с разметкой и подключил его. Все заработало. Спасибо!

Показать все комментарии
7.6
воронка продаж
фильтрация
Технические вопросы
7.x

Здравствуйте.
Скажите пожалуйста, можно ли убрать из воронки продаж определенные стадии?
Стандартный функционал фильтрации не подходит, т.к. стадия в воронке все-равно присутствует, но со значением 0.

Как отфильтровать воронку,чтобы осталось всего 5 нужных стадий?

Нравится

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

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

Если необходимо минимум вмешательства, а стадии используются не совсем как задумано, то можно их отфильтровать следующим образом: в воронке не отображаются конечные не успешные стадии. То есть, можно всем тем, которые не должны отображаться, установить поле End = 1, а поле Successful = 0.

Если же этот функционал используется, то фильтрацию можно добавить только вмешательством в код. Необходимо замещать модуль OpportunityFunnelDrillDownProvider, полностью копировать его код в новый модуль, и вносить необходимые изменения в метод getFunnelAllowedStagesFilters (для версии 7.6) либо в initOpportunityStage (для версии 7.5).

а разве это не решается через Справочники - Стадии продаж?

"Антон Кравченко" написал:а разве это не решается через Справочники - Стадии продаж?

На базе без данных мы удалили ненужные стадии. Правда, клиент не использует референтный процесс

"Антон Кравченко" написал:а разве это не решается через Справочники - Стадии продаж?

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

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

"Пащенко Александр Сергеевич" написал:Изначально был сделан новый процесс продаж и лишние стадии были удалены, но они снова появились после очередного обновления системы и установки данных, привязанных к пакетам.

Лишние стадии мешают не только в воронке продаж, но и в самой карточке продажи

"Пащенко Александр Сергеевич" написал:Изначально был сделан новый процесс продаж и лишние стадии были удалены, но они снова появились после очередного обновления системы и установки данных, привязанных к пакетам.

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

Решение, настроить фильтрацию была принято для того, чтоб не удалять стадии при очередном обновлении.

Показать все комментарии
itil,service,конфигурационная единица,Программные Технологии,ПТ,Центр разработки и внедрения Terrasoft-Поволжье,
Технические вопросы
7.x

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

Связь между КЕ построена на основе детали «Влияет на конфигурации» и поля «Родительская КЕ» с пометками о степени влияния.

Для этого в объект Конфигурационная единица добавлены следующие логические поля:
1. «Полностью выводит из строя КЕ» FullInfluence
2. «Не влияет на КЕ» NotInfluence
3. «Частично выводит из строя КЕ» PartInfluence
И поле InheritStatus – справочник «ConfigItemStatus». В это поле будут записываться состояния, полученные КЕ в результате применения БП автоматизации.
И добавляем новую деталь «Влияет на конфигурации»:

Далее создаем БП, запускающийся при изменении состояния КЕ:

Автоматизация изменения состояний КЕ построена на основе алгоритма рекурсивного обхода дерева:

В скрипте вызываем метод рекурсивного обхода дерева КЕ:

var confItem = new Terrasoft.Configuration.ConfItem(UserConnection);
confItem.FetchFromDB(StartSignal1.RecordId);

ListGuid> confItemIds = new ListGuid>(); // здесь сохраняем Id пройденных узлов
ListGuid> changedIds = new ListGuid>(); // здесь Id КЕ с измененным состоянием

RecursiveUp(confItemIds, confItem, changedIds);

В переменные БП добавляем уникальные идентификаторы, в которые записываем идентификаторы состояний КЕ (эти состояния должны быть добавлены в справочник ConfigItemStatus):
1) PartWorkId
2) NotWorkId
3) WorkId
В бизнес-процесс добавляем метод:

void RecursiveUp(ListGuid> confItemIds, Terrasoft.Configuration.ConfItem confItem, ListGuid> changedIds)
{

        var updateTemplate = "Update ConfItem Set InheritStatusId = '{0}' Where Id = '{1}'"; // шаблон запроса обновления статуса КЕ
//Находим КЕ, указанные на детали «Влияние», на которые влияет КЕ текущего узла дерева:
        var esq = new EntitySchemaQuery(UserConnection.EntitySchemaManager, "ConfItemInfluence");
        esq.AddAllSchemaColumns();
        esq.Filters.Add(esq.CreateFilterWithParameters(FilterComparisonType.Equal, "ParentConfItem", confItem.Id));
        esq.Filters.Add(esq.CreateFilterWithParameters(FilterComparisonType.Equal, "NotInfluence", 0));

        var entities = esq.GetEntityCollection(UserConnection);

//Обходим все найденные КЕ:
        foreach (var entity in entities)
        {
                var confItemInfluenceDetail = entity as Terrasoft.Configuration.ConfItemInfluence;

                var confItemInfluence = confItemInfluenceDetail.ConfItem;

//Проверяем обходили ли мы уже полученный узел:

                if (!confItemIds.Contains(confItemInfluenceDetail.ConfItemId) && confItemInfluence != null && confItemInfluence.FetchFromDB(confItemInfluenceDetail.ConfItemId))
                {

//Далее в зависимости от состояния КЕ текущего узла, меняем статус КЕ, указанной на детали:
                        if (confItem.InheritStatusId == NotWorkId)
                        {
                                if (confItemInfluenceDetail.FullInfluence)
                                {
                                        (new CustomQuery(UserConnection, String.Format(updateTemplate, NotWorkId, confItemInfluenceDetail.ConfItemId))).Execute();
                                        confItemInfluence.InheritStatusId = NotWorkId;                         
                                }
                                else if (confItemInfluence.InheritStatusId != NotWorkId)
                                {
                                        (new CustomQuery(UserConnection, String.Format(updateTemplate, PartWorkId, confItemInfluenceDetail.ConfItemId))).Execute();
                                        confItemInfluence.InheritStatusId = PartWorkId;
                                }
                        }
                        else if (confItem.InheritStatusId == PartWorkId)
                        {
                                if (confItemInfluenceDetail.FullInfluence && confItemInfluence.InheritStatusId != NotWorkId)
                                {
                                        (new CustomQuery(UserConnection, String.Format(updateTemplate, PartWorkId, confItemInfluence.Id))).Execute();
                                        confItemInfluence.InheritStatusId = PartWorkId;
                                }
                        }
                        else if (confItem.InheritStatusId == WorkId)
                        {
                                (new CustomQuery(UserConnection, String.Format( updateTemplate, WorkId, confItemInfluenceDetail.ConfItemId))).Execute();
                                        confItemInfluence.InheritStatusId = WorkId;
                        }

//Проверяем наличие КЕ, которые влияют на КЕ текущего узла:

                        var notWorkingCount = (new CustomQuery(UserConnection, String.Format("Select Count(1) from ConfItemInfluence ci join ConfItem c on c.Id = ci.ParentConfItemId Where ConfItemId = '{0}' and ci.NotInfluence = 0 and c.InheritStatusId = '{1}'  and ci.FullInfluence = 1", confItemInfluence.Id, NotWorkId))).ExecuteScalarint>();

//Если такие КЕ найдены, то меняем состояния КЕ текущего узла:
                        if (notWorkingCount > 0)
                        {
                                (new CustomQuery(UserConnection, String.Format(updateTemplate, NotWorkId, confItemInfluence.Id))).Execute();
                                CompareStatus(confItemInfluence, NotWorkId, changedIds);
                                confItemInfluence.StatusId = NotWorkId;
                                confItemIds.Add(confItemInfluence.Id);
                        }
                        else if ((new CustomQuery(UserConnection, String.Format("Select Count(1) from ConfItemInfluence ci join ConfItem c on c.Id = ci.ParentConfItemId Where ConfItemId = '{0}' and ci.NotInfluence = 0 and ( (c.InheritStatusId = '{1}') or (c.InheritStatusId = '{2}'  and ci.FullInfluence = 0) )", confItemInfluence.Id, PartWorkId, NotWorkId))).ExecuteScalarint>() > 0)
                        {
                                (new CustomQuery(UserConnection, String.Format updateTemplate, PartWorkId, confItemInfluence.Id))).Execute();
                                confItemInfluence.StatusId = PartWorkId;
                                confItemIds.Add(confItemInfluence.Id);
                        }

//Переходим к следующему узлу дерева:
                        RecursiveUp(confItemIds, confItemInfluence, changedIds);
                       
                }
        }
}

Алгоритм состоит в следующем: Для имеющейся КЕ находим все те КЕ, на которые она оказывает частичное или полное влияние и изменяем состояние связанной КЕ. Вместе с этим запоминаем идентификаторы КЕ, которые мы прошли или состояние которых изменилось (confItemIds /changedIds). Это помогает решить две задачи: по списку измененных КЕ можно отослать уведомления об их изменении, либо, если мы предполагаем, что в дереве могут быть циклические зависимости, не обходить уже пройденные узлы.
Изменения состояний КЕ производятся через CustomQuery, т.к. процесс автоматизации запускается по сигналу изменения состояния и нельзя чтобы при изменении состояния КЕ при обходе дерева процесс снова запускался.
Автоматизация связей проблем/обращений/КЕ происходит с помощью следующего бизнес-процесса:

В данном случае алгоритм простой:
Читаем данные обращения

caseItem.FetchFromDB(recordId);

var problemId = caseItem.ProblemId;
var statusId = caseItem.StatusId;

var closeCaseStatus = new Guid("3E7F420C-F46B-1410-FC9A-0050BA5D6C38");
var newCaseStatus = new Guid("AE5F2F10-F46B-1410-FD9A-0050BA5D6C38");
var workCaseStatus = new Guid("7E9F1204-F46B-1410-FB9A-0050BA5D6C38");

var closeProblemStatus = new Guid("459361BE-C3B5-4D6B-9DEC-C8DCB49AE5B3");
var newProblemStatus = new Guid("340A7737-3CFF-4BED-A292-B83CD25DA3DA");
var workProblemStatus = new Guid("1B79DF4C-17AB-4A75-95E3-C53E3793F1C6");

var workConfItemStatus = new Guid("742E7BCE-6191-4AA5-9D16-DB26CF87BC98");
var notWorkConfItemStatus = new Guid("5C97181E-090F-4893-9A21-DEF3161F2347");

var newProblemStatusId = Guid.Empty;
var newConfItemStatusId = Guid.Empty;

Устанавливаем новые статусы обращений и проблем

if(statusId == closeCaseStatus)
{
        newProblemStatusId = closeProblemStatus;
        newConfItemStatusId = workConfItemStatus;
}
else if(statusId == newCaseStatus)
{
        newProblemStatusId = newProblemStatus;
        newConfItemStatusId = notWorkConfItemStatus;
}
else if(statusId == workCaseStatus)
{
        newProblemStatusId = workProblemStatus;
        newConfItemStatusId = notWorkConfItemStatus;
}

Находим зависимые КЕ обращения:

var confItemList = new ListGuid>();
var esq = new EntitySchemaQuery(UserConnection.EntitySchemaManager, "ConfItemInCase");

...

var entities = esq.GetEntityCollection(UserConnection);
                       
foreach(var entity in entities)
{
        var confItemInCase = entity as Terrasoft.Configuration.ConfItemInCase;
        confItemList.Add(confItemInCase.ConfItemId);
}

и проблемы:
var problem = caseItem.Problem;

if(problem != null && problem.FetchFromDB(problemId))
{

        if(!confItemList.Contains(problem.ConfItemId))
        {
                confItemList.Add(problem.ConfItemId);
        }

        if(newProblemStatusId != Guid.Empty)
        {
               

Обновляем состояние связанных проблем:
new CustomQuery(UserConnection, String.Format("Update Problem Set StatusId = '{0}' Where Id = '{1}'", newProblemStatusId, problemId)).Execute();
                if(statusId == closeCaseStatus)
                {
                        new CustomQuery(UserConnection, String.Format("delete from Reminding Where SubjectId = '{0}'", problemId)).Execute();
                }
        }
}

Проходим все зависимые КЕ и меняем их статус, инициируя процесс автоматизации состояний КЕ:

if(newConfItemStatusId != Guid.Empty)
{
        foreach(var confItemId in confItemList)
        {
                var confItem = new Terrasoft.Configuration.ConfItem(UserConnection);
                if(confItem.FetchFromDB(confItemId))
                {
                        confItem.StatusId = newConfItemStatusId;
                        confItem.Save();
                }
        }
}

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

Нравится

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

Добрый день, подскажите где можно почитать или как алгоритмический вставить в левую панель свои кнопки?
Вроде подобного:
1
Задача стоит следующая - добавить кнопку, привязать к ней метод который будет изменять системную переменную, в зависимости от значения true или false кнопка изменяет внешний вид.
Покопался в файлах нашел CTIBase.CtiLeftPanelUtilities думаю это верное направление, но никак не могу структурировать это все

Нравится

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

У Вас не корректно прикрепился скриншот. Битый файл.

Попробуйте посмотерть релазиацию в схеме "LeftPanelTopMenuModule" (Рис. 1).


Рис. 1

Это не битый файл, это временное хранилище, через сутки ссылка становится битой
Продублирую еще раз
1
В общем да, LeftPanelTopMenuModule это то что надо, но можно пояснений что там происходит?
Попробовал наследоваться от этой схемы чтобы попробовать для начала добавить туда элемент, но пропали иконки, открыл стандартную, чтобы иконки достать, в ней они есть но не отображаются

Олег, Вы же можете прикрепить изображение как вложенный файл. Необязательно же хранить на хостинге.

В модуле описан функционал верхнего меню.
А что консоль говорит? Отладку делали?

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

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

Здравствуйте, форумчане!

В процессе работы с Sales 7.6 возник вопрос, как изменить количество знаков после запятой в курсе валют (по умолчанию 2 знака(хх,хх), нужно сделать 4 знака(хх,хххх)). Как это сделать?

Заранее благодарен за ответы.

Нравится

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

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

Ответ Вы можете прочитать во вложенном pdf файле.

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

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

Спасибо!

Скажите, какой метод в CurrencyRateEditPage отвечает за количество знаков после запятой?

Нашел метод
private void UpdateRateEdit() {
RateEdit.Image = new ControlImage {};
RateEdit.DecimalPrecision = 4;
RateEdit.ModifiedInSchemaUId = new Guid("dffcf096-6982-4a07-92da-973f4261fd07");
}

изменил RateEdit.DecimalPrecision с 2 на 4, но при этом ничего не поменялось, все еще 2 знака после запятой. Подскажите, может я что-то упустил?

Добрый день!
У Вас есть объект CurrencyRate, который содержит колонку Rate. Эта колонка имеет тип Currency, который имеет Precision = 2. Чтобы вы могли использовать 4 знака после запятой, то у Вас есть 2 варианта:
1. Добавить свой объект CurrencyRateEx (к примеру) и создать в нем поле Rate как decimal (0.0001)
Далее по всей конфигурации заменить имя схемы CurrencyRate на CurrencyRateEx (во всех клиентских модулях)

2. Расширить объект CurrenctRate и добавить свое поле RateEx (к примеру), которое будет decimal (0.0001). Далее заменить по всех конфигурации использование поля Rate на RateEx, а в расширяющем объекте для старого поля Rate установить режим использования "никогда".

Также, не зависимо от этих двух вариантов Вам нужно будет изменять страницу редактирования справочника (CurrencyRateEditPage)

А нельзя просто поменять тип колонки Rate, поставив Precision = 4?

"Владимир Соколов" написал:А нельзя просто поменять тип колонки Rate, поставив Precision = 4?

Владимир, простая замена типа с изменением значения поля на 4 не решит вопрос корректно.

"Артем Гура" написал:(во всех клиентских модулях)

И во всех процессах (например, в InvoiceProduct и других)

Вообщем, надо решать этот вопрос глобально, а не у каждого клиента в каждом проекте, так как все центробанки дают курс валют с точностью 4 знака

Владимир, данную информацию уже передали в отдел разработки для реализации в последующих версиях продукта.

"Артем Гура" написал:

Добрый день!

У Вас есть объект CurrencyRate, который содержит колонку Rate. Эта колонка имеет тип Currency, который имеет Precision = 2. Чтобы вы могли использовать 4 знака после запятой, то у Вас есть 2 варианта:

1. Добавить свой объект CurrencyRateEx (к примеру) и создать в нем поле Rate как decimal (0.0001)

Далее по всей конфигурации заменить имя схемы CurrencyRate на CurrencyRateEx (во всех клиентских модулях)

2. Расширить объект CurrenctRate и добавить свое поле RateEx (к примеру), которое будет decimal (0.0001). Далее заменить по всех конфигурации использование поля Rate на RateEx, а в расширяющем объекте для старого поля Rate установить режим использования "никогда".

Также, не зависимо от этих двух вариантов Вам нужно будет изменять страницу редактирования справочника (CurrencyRateEditPage)

Спасибо, Артем, буду реализовывать.

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

Как в bpm'online 7.x можно поменять формат даты на dd.MM.yyyy (с точками вместо косой черты)? И поменять разделитель тысяч с запятой на пробел в числах? И десятичную точку на запятую?

Американский формат - это хорошо, но у локальных пользователей вызывает некоторое отторжение.

Нравится

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

Здравствуйте! Форматы вывода прописаны в локализации.

Формат даты, можно изменить если в приложении присутствует английская локализация.
Локализация меняется в профиле пользователя:

Для локализации «en-GB» формат даты выглядит как ДД/ММ/ГГГГ (Рис. 2).

Для локализации «en-US» формат даты выглядит как ММ/ДД/ГГГГ (Рис. 3).

Для локалицазии "ru-RU" используется как раз "." в качестве разделителя для дат (ДД.ММ.ГГГГ), а также " " в качестве разделителя для чисел (пример 1 000 000).

Алексей, вот ни разу не видел продукт линейки bpmonline, где после переключения en-US / ru-RU весь интерфейс отображается с другим языком, все же как правило в поставке язык один :wink:

А никак это по другому не подлечить? Так как "плюсанул" тему не зря - имею от пользователей eng версии такой же вопрос про формат даты, ну не нравится им буржуйский mm/dd/yyyy, хотят dd.mm.yyyy

"Демьяник Алексей Олегович" написал:Для локалицазии "ru-RU" используется как раз "." в качестве разделителя для дат (ДД.ММ.ГГГГ), а также " " в качестве разделителя для чисел (пример 1 000 000).

А как это сделать для английской локализации?

Здравствуйте, коллеги!
Есть следующее решение:
1) Добавьте исходный код (source code) в конфигурации.
2) В созданную схему исходного кода добавьте исходный код:

namespace Terrasoft.Configuration
{
using System;
using System.Text;
using System.Collections.Generic;
using System.Data;
using Terrasoft.Common;
using Terrasoft.Core;
using Terrasoft.Core.Entities;
using Terrasoft.Core.Factories;
using Terrasoft.Nui;
using Terrasoft.UI.WebControls; 
using Terrasoft.Core.DB;
[Terrasoft.Core.Factories.Override]
public class DevConfigurationSectionHelper: ConfigurationSectionHelper {
public DevConfigurationSectionHelper(UserConnection userConnection) : base(userConnection) {
}
public override string GetConfigurationScript(UserConnection userConnection) {
var baseScript = base.GetConfigurationScript(userConnection);
return baseScript + @"Terrasoft.Resources.CultureSettings.dateFormat = 'd.m.y';";
/*
return baseScript + @"Terrasoft.Resources.CultureSettings.dateFormat = 'd/m/y';";
*/
}
}
}

3) Сохраните в метаданных
4) Опубликуйте.

В результате дата будет отображаться как 01.01.0001 (если убрать комментарий и закомментировать предыдущую строчку, то дата будет отображаться как 01/01/0001).

Работоспособность протестирована на 760.

Вот это другое дело :)
Спасибо

"Демьяник Алексей Олегович" написал:Работоспособность протестирована на 760.

И на 7.5 работает! Спасибо!

А как поменять формат Decimal? Чтобы пробел как разделитель тысяч и десятичная точка?

Владимир, абсолютно аналогично.

Соответствующие параметры - CultureSettings.decimalSeparator и CultureSettings.thousandSeparator.

Спасибо огромное!

Уже интересно, что еще можно сделать с помощью CultureSettings :)

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

Terrasoft.Resources.CultureSettings = {
	dateFormat: "d.m.Y",
	timeFormat: "G:i",
	thousandSeparator: " ",
	decimalSeparator: ",",
	todayMessage: "Сегодня",
	shortDayNames: ["Вс", "Пн", "Вт", "Ср", "Чт", "Пт", "Сб"],
	monthNames: ["Январь", "Февраль", "Март", "Апрель", "Май",
		"Июнь", "Июль", "Август", "Сентябрь", "Октябрь", "Ноябрь", "Декабрь"],
	startDay: 1,
	numberGroupSizes: 3
};

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

Спасибо

"Артем Гура" написал:Всем добрый день!
Данные "внедрения" приведут к ошибкам обновления.
Мы настоятельно не рекомендуем это делать!
Также, мы не можем оставить данную информацию для "передачи опыта"

Спасибо

Сказали, как нельзя, скажите, как можно

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

Внесение подобных изменений, не влекущих за собой возможных ошибок при обновлении, не предусмотрено в текущих версиях BPM'Online.

"Мартыненко Сергей" написал:

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

Внесение подобных изменений, не влекущих за собой возможных ошибок при обновлении, не предусмотрено в текущих версиях BPM'Online.

То есть, пока Terrasoft не научит систему менять формат даты и чисел, можно забыть про обновления?

"Владимир Соколов" написал:

То есть, пока Terrasoft не научит систему менять формат даты и чисел, можно забыть про обновления?

Здравствуйте, Владимир!

Данные изменения могут повлиять на корректность обновления, так как изменяются системные переменные ядра. Функционал, предусматривающий пользовательские изменения формата дат/чисел, разделителей пока что не планируется.

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

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