Доброго дня, коллеги!

 

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

 

Возможно ли это в Creatio? Просто я вроде читал, но ничего похожего не увидел, если так можно, был бы рад ответу и если это есть где-то на академии, был бы рад получить ссылку.

 

Заранее благодарю!

Нравится

1 комментарий
Лучший ответ

Здравствуйте, Михаил!

 

К сожалению, базовыми средствами реализовать раздачу прав на отдельный справочник, не получится. На данный момент нужно давать права всем на CanManageLookups.
Команда разработки ответственная за этот функционал в курсе существования этой проблемы и будет работать над внедрением ее решения в будущих релизах Creatio.
 

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

Для того, чтоб справочник можно было отобразить как раздел, начиная с версии 7.16.2 добавлена возможность создать раздел, используя существующий объект системы. Только нужно учесть, что если объект справочника стандартный (без Usr),  в таком разделе теги и группы работать не будут, поскольку для них не получится создать таблицы в Custom.

Здравствуйте, Михаил!

 

К сожалению, базовыми средствами реализовать раздачу прав на отдельный справочник, не получится. На данный момент нужно давать права всем на CanManageLookups.
Команда разработки ответственная за этот функционал в курсе существования этой проблемы и будет работать над внедрением ее решения в будущих релизах Creatio.
 

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

Для того, чтоб справочник можно было отобразить как раздел, начиная с версии 7.16.2 добавлена возможность создать раздел, используя существующий объект системы. Только нужно учесть, что если объект справочника стандартный (без Usr),  в таком разделе теги и группы работать не будут, поскольку для них не получится создать таблицы в Custom.

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

Добрый день, коллеги!

 

Такой вопрос: Я создаю несколько справочников, они должны хранить в своих полях id других справочников. Как мне реализовать эту связь в "Управление конфигурацией"? И как мне правильно их связать?

Нравится

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

Добрый день! Пример данной реализации можете посмотреть, например, в объекте LeadProduct.

Справочник основан на объекте. Чтобы добавить в него связь с другими справочниками (=объектами) найдите объект справочника и добавьте туда поле с типом "Справочник" и укажите название справочника, связь с которым необходимо добавить, при необходимости выполнив замещение объекта в пользовательском пакете (подробнее читайте в академии)

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

Добрый день, коллеги!

 

Недавно вышло обновление к Creatio, где расширили функционал oData, а точнее добавили действие upsert, я хотел бы узнать, как правильно генерировать данный запрос?

Я работаю через postman.

 

Заранее спасибо!

Нравится

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

Михаил, для того, чтобы сделать upsert, нужно выполнить patch-запрос с указанием id в списке полей. Раньше если записи не было, возвращало ошибку, сейчас производится вставка. А если есть, то и раньше, и сейчас — изменение. Готовых именно таких примеров нет, о patch есть в справочнике по API.

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

Доброго дня, коллеги! Есть два вопроса:

 

  1. Возникла такая потребность, что в справочнике необходимо отобразить изображение и как его правильно загрузить в элемент справочника? 
  2. Как мне реализовать связь один к одному и один ко многим в справочниках? Мне необходимо вытягивать id-поле из одного справочника и присваивать его в другом. Есть ли какой-то способ?

 

Нравится

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

Добрый день. По первому пункту такое реализовано в справочнике "Приоритеты обращений" CasePriority (есть в продукте Service). Там можно провалиться в запись справочника и загрузить картинку.

Общий порядок действий примерно таков:

1) создать объект. назовем его BCActivityColor. Наследуем его от базового справочника и добавляем колонку BCImage (Ссылка на изображение).
Не забываем в настройках объекта установить "Изображение" - нашу колонку. запомним UID объекта

2) Создадим для справочника страницу редактирования (я взял коробочную CasePriorityLookupEditPageV2 и выкинул лишнее).  Реализуем там загрузку картинок.
страницу наследуем от Базовая страница справочника ( UIv2 ). пример: CasePriorityLookupEditPageV2

запомним UID странички

3) зарегистрируем нашу страницу редактирования для объекта (sql). 
Привяжем BCActivityColor_SysModuleEntity (указывается UId объекта который создали в п.1) и BCActivityColor_SysModuleEdit (указывается UId схемы странички которую создали в п.2)
не забыть перезайти в почистить кэш.

Пример регистрации страницы справочника CaseCasePriority_SysModuleEdit и CaseCasePriority_SysModuleEntity

4) после заполнения справочника не забыть привязать SysImage и значения нашего нового справочника.

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

Коллеги, всем доброго дня!

У нас есть справочник, абсолютно обычный, никакого кастома. Некий отдельный процесс наполняет данный справочник записями в соответствии с алгоритмом своей работы, порядка 2-3 тысяч записей. После обработки данных записей пользователи производят удаление стандартными методами: Действия - Выбрать все записи, затем Удалить. По истечению некоторого времени получаем ошибку вида: "Произошла ошибка. Пожалуйста, обратитесь к администратору". Скажите, возможно есть какие-то подводные камни у данного механизма удаления, что может стать причиной такого поведения, как можно диагностировать и устранить проблему? Справочник абсолютно линейный и простой, никакого кастомного кода в нем нет, логики на объекте справочника тоже нет.

Буду признателен за любые идеи в решении данного вопроса!

Нравится

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

Добрый день. Ошибка возникает при процессе удаления? Пару вариантов, которые могут быть причинами ошибки:

- у пользователя под которым выполняется данная операция (удалить), нет соответствующих прав;  

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

Добрый день.

 

Часто такая ошибка возникает, когда происходит свал по тайм ауту.

 

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

 

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

Алла Савельева,

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

На тайм аут это действительно больше всего похоже. Но пока не знаем как выйти из положения, разве что написать кастомный сервис зачистки данного справочника. Удаление частями выход, но это крайне неудобно пользователям (как бить записи на группы, если их 3000, и помечать их к удалению)?

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

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

 

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

 

Ещё длительное удаление может быть связано с логикой, которая добавлена во встроенном или отдельном БП на событии удаления для этого объекта.  В таком случае она отработает только при удалении средствами EntiteSchemaQuery (оно происходит и при удалении пользователем вручную). А при удалении средствами класса Delete она не вызывается: будет намного быстрее, но логика не отработает, что нужно будет учесть и реализовать нужные вычисления отдельно.

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

Добрый день

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

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

Но! Если я дам права на CanManageLookups, то получается, пользователь сможет вести практически все справочники через пункт Добавить в выпадающем списке. Или что хуже додумается перейти через главную страницу к разделу справочники.

Есть еще идеи?

Нравится

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

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

 

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

 

Но нужно ещё учесть, что на уровне объекта «Базовый справочник», от которого унаследованы остальные, есть проверка на это право:

Скрипт запускает функцию:

public virtual void CheckCanManageLookups() {
	UserConnection.DBSecurityEngine.CheckCanExecuteOperation("CanManageLookups");
}

Чтобы она не срабатывала, нужно в объекте нужного справочника переопределить её пустой. Насколько я понимаю, для ряда справочников это уже сделано в стандартной поставке.

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

Добрый день!

Суть такова. В системе есть справочник в который занесены номера недель и соответствующие им календарные даты. (Например: Номер недели: 3; Дата: 14.01.2019 - 18.01.2019). 

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

Нравится

6 комментариев
Лучший ответ

Возможность есть 

1 БП запускайте по расписанию

2 С помощью элемента формула можно получить номер текущей неделе дальше обновить или что вам нужно сделать с этой записью

По работе в формуле с датами более подробно смотри тут

Возможность есть 

1 БП запускайте по расписанию

2 С помощью элемента формула можно получить номер текущей неделе дальше обновить или что вам нужно сделать с этой записью

По работе в формуле с датами более подробно смотри тут

Накидал на C# скрипт, который выдает список с данными (неделя, начало, конец, год). осталось вызывать раз в год

var data = WeekWorker.GetYearWeekData(2019);

и данные парсить в справочник

using System;
using System.Collections.Generic;
using System.Globalization;
 
namespace TestApp
{
    public class WeekData
    {
        public int year { get; set; }
        public int week { get; set; }
        public DateTime weekStart { get; set; }
        public DateTime weekEnd { get; set; }
    }
 
    public class WeekWorker
    {
        public static List<WeekData> GetYearWeekData(int year)
        {
            var weeksdata = new List<WeekData>();
 
            int weeks = GetWeeksInYear(year);
            for (int i = 1; i <= weeks; i++)
            {
                var firstDay = FirstDateOfWeekISO8601(year, i);
                var lastDay = firstDay.AddDays(6);
 
                weeksdata.Add(new WeekData() { year = year, week = i, weekStart = firstDay, weekEnd = lastDay });
            }
 
            return weeksdata;
        }
        public static int GetWeeksInYear(int year)
        {
            DateTimeFormatInfo dfi = DateTimeFormatInfo.CurrentInfo;
            DateTime date1 = new DateTime(year, 12, 31);
            Calendar cal = dfi.Calendar;
            int weeks = cal.GetWeekOfYear(date1, dfi.CalendarWeekRule, dfi.FirstDayOfWeek);
            return weeks;
        }
 
        public static DateTime FirstDateOfWeekISO8601(int year, int weekOfYear)
        {
            DateTime jan1 = new DateTime(year, 1, 1);
            int daysOffset = DayOfWeek.Thursday - jan1.DayOfWeek;
 
            // Use first Thursday in January to get first week of the year as
            // it will never be in Week 52/53
            DateTime firstThursday = jan1.AddDays(daysOffset);
            var cal = CultureInfo.CurrentCulture.Calendar;
            int firstWeek = cal.GetWeekOfYear(firstThursday, CalendarWeekRule.FirstFourDayWeek, DayOfWeek.Monday);
 
            var weekNum = weekOfYear;
            // As we're adding days to a date in Week 1,
            // we need to subtract 1 in order to get the right date for week #1
            if (firstWeek == 1)
            {
                weekNum -= 1;
            }
 
            // Using the first Thursday as starting week ensures that we are starting in the right year
            // then we add number of weeks multiplied with days
            var result = firstThursday.AddDays(weekNum * 7);
 
            // Subtract 3 days from Thursday to get Monday, which is the first weekday in ISO8601
            return result.AddDays(-3);
        }
    }
 
}

 

Григорий Чех пишет:

Возможность есть 

1 БП запускайте по расписанию

2 С помощью элемента формула можно получить номер текущей неделе дальше обновить или что вам нужно сделать с этой записью

По работе в формуле с датами более подробно смотри тут

Расскажите, пожалуйста, подробнее про то как построить такой БП, а то я не понимаю какие элементы там должны присутствовать.

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

Если Вы хотите заказать разработку такой логики полностью «под ключ», лучше будет заказать её у одной из компаний, зарегистрированных в маркете в каталоге услуг

Добавить комментарий

Зверев Александр пишет:

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

Если Вы хотите заказать разработку такой логики полностью «под ключ», лучше будет заказать её у одной из компаний, зарегистрированных в маркете в каталоге услуг

Мало ли кто-то из комьюнити уже реализовывал схожий процесс и поделится опытом на безвозмездной основе. За деньги вообще, мне кажется, все связанное с CRM можно решить.

Поделились же, в первом и втором комментарии.

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

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

Добрый день,

 

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

есть Справочник улиц (Street) у которого соответственно есть принадлежность к выше стоящим элементам(Городам, Районам, Регионам и др.) 

Выглядит примерно следующим образом

╔══════════════╤═════════════════════╤══════════════════════════════════════╤══════════════════════════════════════╤══════════════════════════════════════╤══════════════════════════════════════╗
║ Name         │ TerritorialObjectId │ LocalityId                           │ DistrictId                           │ RegionId                             │ CountryId                            ║
╠══════════════╪═════════════════════╪══════════════════════════════════════╪══════════════════════════════════════╪══════════════════════════════════════╪══════════════════════════════════════╣
║ ул. Королёва │ NULL                │ NULL                                 │ NULL                                 │ B0FDED10-AEE0-4F1B-9C8D-198F7C154257 │ 5A1FEFDA-56A4-48A2-BC77-E40C71EEC73B ║
╟──────────────┼─────────────────────┼──────────────────────────────────────┼──────────────────────────────────────┼──────────────────────────────────────┼──────────────────────────────────────╢
║ ул. Ф.Торо   │ NULL                │ 967FC3D7-EBBA-4B76-AEDD-FE1CA5B48157 │ 7B11D4CE-D3E2-487F-BE03-A620015FB4FA │ EED82307-32D6-47EF-BDD8-FA64FE399614 │ 5A1FEFDA-56A4-48A2-BC77-E40C71EEC73B ║
╚══════════════╧═════════════════════╧══════════════════════════════════════╧══════════════════════════════════════╧══════════════════════════════════════╧══════════════════════════════════════╝

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

Бизнес правило по улице заполнено следующим образом

"Street": {
	"FiltrationStreetByTerritorialObject": {
		ruleType: BusinessRuleModule.enums.RuleType.FILTRATION,
		autocomplete: true,
		autoClean: true,
		baseAttributePatch: "TerritorialObject",
		comparisonType: Terrasoft.ComparisonType.EQUAL,
		type: BusinessRuleModule.enums.ValueType.ATTRIBUTE,
		attribute: "TerritorialObject"
	},
	"FiltrationStreetByLocality": {
		ruleType: BusinessRuleModule.enums.RuleType.FILTRATION,
		autocomplete: true,
		autoClean: true,
		baseAttributePatch: "Locality",
		comparisonType: Terrasoft.ComparisonType.EQUAL,
		type: BusinessRuleModule.enums.ValueType.ATTRIBUTE,
		attribute: "Locality"
	},
	"FiltrationStreetByDistrict": {
		ruleType: BusinessRuleModule.enums.RuleType.FILTRATION,
		autocomplete: true,
		autoClean: true,
		baseAttributePatch: "District",
		comparisonType: Terrasoft.ComparisonType.EQUAL,
		type: BusinessRuleModule.enums.ValueType.ATTRIBUTE,
		attribute: "District"
	},
	"FiltrationStreetByRegion": {
		ruleType: BusinessRuleModule.enums.RuleType.FILTRATION,
		autocomplete: true,
		autoClean: true,
		baseAttributePatch: "Region",
		comparisonType: Terrasoft.ComparisonType.EQUAL,
		type: BusinessRuleModule.enums.ValueType.ATTRIBUTE,
		attribute: "Region"
	},
	"FiltrationStreetByCountry": {
		ruleType: BusinessRuleModule.enums.RuleType.FILTRATION,
		autocomplete: true,
		autoClean: true,
		baseAttributePatch: "Country",
		comparisonType: Terrasoft.ComparisonType.EQUAL,
		type: BusinessRuleModule.enums.ValueType.ATTRIBUTE,
		attribute: "Country"
	}
}

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

Я что то упускаю?

Нравится

4 комментария
Лучший ответ

Сериков Асхат Кайратович,

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

Это решается также через другое свойство атрибута - dependencies.

Подробнее можно почитать здесь и посмотреть пример вот здесь.

Насколько мне известно, такой код работать не будет.

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

Алла Савельева,

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

autocomplete: true,

должен был выполнять

Сериков Асхат Кайратович,

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

Это решается также через другое свойство атрибута - dependencies.

Подробнее можно почитать здесь и посмотреть пример вот здесь.

Алла Савельева,

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

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

Всем привет!

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

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

В голову приходит подобный код

if (this.isAddMode() || this.isCopyMode()) {

this.set("UsrStatus", значение справочника)

}

Но ничего подобного я не обнаружил в исходниках страницы продаж или лидов.

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

Вопрос два, как установить значение справочного поля через set? 

Знаю, что качестве второго аргумента в set нужно передавать конструкцию {value: "Guid",
                                              displayValue: "Caption" }

Как правильно получить guid, зная только название справочного поля? Напрямую писать guid это слишком костыльно выглядит.

Нравится

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

1) На уровне объекта у колонки св-во: "значение по умолчанию". смотрим на какое справочное поле биндится полоска стадий, ну и соответственно ему задаём значение.
2) this.loadLookupDisplayValue(guid, #колонка_объекта_в_которую_надо_установить_значение#, callback, scope)

Спасибо. Оказалось все очень просто

Варфоломеев Данила, а можно еще пример работы с методом loadLookupDisplayValue?

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

Трефилов Павел Сергеевич пишет:
пример работы с методом

this.loadLookupDisplayValue("UsrContractState", "d7e40d7c-1fa4-49cb-a0d5-57a936f9a463"); //подменить на id значения "Подписан". Метод установит значение.
 
//или, если нужен коллбек:
 
this.loadLookupDisplayValue("UsrContractState", "d7e40d7c-1fa4-49cb-a0d5-57a936f9a463", function() {
    //сюда провалимся после того, как система установит значение. Удобно, когда надо дальше работать со значением UsrContractState.
}, this)

 

Варфоломеев Данила,

Понятно, по сути не сильно это отличается от установки через set.

 this.set("UsrContractState", {value: "d7e40d7c-1fa4-49cb-a0d5-57a936f9a463", displayValue: "Подписан"});

Единственный бонус, что можно работать с колбеком.

Трефилов Павел Сергеевич пишет:
Единственный бонус, что можно работать с колбеком.

Не только. К UsrContractState через lookupListConfig/columns вы можете подгружать допполя. Так вот в случае вызова loadLookupDisplayValue, функция их подгрузит, через set - нет.

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

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

Нравится

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

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

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

Если у Вас значения полей в приложении и в БД все же отличаются, напишите о проблеме на support@terrasoft.ru для более детального анализа (необходим будет доступ к БД и к приложению).

Одеяненко Юлия, я сервер перезагрузил - оно так и осталось!

Алексей, в таком случае необходим более детальный анализ кейса. Напишите о проблеме на support@terrasoft.ru, необходим будет доступ к БД и к приложению

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