Добрый день! В планировании производится расчет Плана, Факта и Потенциала, стоит задача значения Факта заменить на кастомизированное поле из продаж. Как это можно сделать? И какой пакет за это отвечает?
Значение нужно вычислять в хранимке tsp_RecalculateForecastFact, в блоке
SET @SQLText = N'
SELECT
(SELECT SUM(ISNULL(fiv.[Value], 0))
FROM [ForecastItemValue] fiv
WHERE fiv.[ForecastItemId] = @P5
AND fiv.[PeriodId] = @P6
AND fiv.[ForecastIndicatorId] = @P7
) PlanAmount,
(SELECT SUM(ISNULL(o.[Amount], 0))
FROM [Opportunity] o
WHERE o.[StageId] = @P1
AND o.[DueDate] >= @P2
AND o.[DueDate] < @P3
AND o.' + @ColumnName + N' = @P4
) FactAmount,
(SELECT SUM(ISNULL(o.[Amount], 0) * ISNULL(o.[Probability], 0) / 100)
FROM [Opportunity] o
INNER JOIN [OpportunityStage] os ON os.[Id] = o.[StageId]
WHERE os.[End] = 0
AND o.[DueDate] >= @P2
AND o.[DueDate] < @P3
AND o.' + @ColumnName + N' = @P4
) PotentialAmount'
Заголовок индикатора нужно менять в таблице ForecastIndicator. Изменять нужно только Name, поле Code не трогать.
Заголовок индикатора нужно менять в таблице ForecastIndicator. Изменять нужно только Name, поле Code не трогать.
Спасибо! А если нет доступа к таблицам?
можно сделать так?
(SELECT SUM(ISNULL(fiv.[Value], 0))
FROM [ForecastItemValue] fiv
WHERE fiv.[ForecastItemId] = @P5
AND fiv.[PeriodId] = @P6
AND fiv.[ForecastIndicatorId] = @P7
) PlanAmount,
(SELECT SUM(ISNULL(o.[UsrMarginAmount], 0))
FROM [Opportunity] o
WHERE o.[StageId] = @P1
AND o.[DueDate] >= @P2
AND o.[DueDate] < @P3
AND o.' + @ColumnName + N' = @P4
) FactAmount,
(SELECT SUM(ISNULL(o.[UsrMarginAmount], 0) * ISNULL(o.[Probability], 0) / 100)
FROM [Opportunity] o
INNER JOIN [OpportunityStage] os ON os.[Id] = o.[StageId]
WHERE os.[End] = 0
AND o.[DueDate] >= @P2
AND o.[DueDate] < @P3
AND o.' + @ColumnName + N' = @P4
) PotentialAmount'
И ещё уточнение, я же не могу править пакет CoreForecast. поэтому просто создаю tsp_RecalculateForecastFact в Custom?
Игорь, пользователь в принципе может выполнить любой скрипт, имея доступ в конфигурацию.
Для этого необходимо перейти в конфигурацию, выбрать пакет Custom и перейдя на вкладку "SQL-сценарии" добавить нужный скрипт. Далее для него выполнить действие «Установить выбранные элементы» в меню «SQL скрипт».
Но настоятельно рекомендуем перед применением скриптов выполнять бэкап.
По сути вопроса: да, хранимку Вы можете поправить так, как написали. Только следует скопировать полный текст оригинальной хранимки, внести свои изменения и выполнить действие установки.
По индикатору планирования: нужно создать в пакете Custom скрипт:
UPDATE ForecastIndicator
SET Name =<Новое название индикатора в одинарных кавычках>
WHERE Code ='Fact'
Маю задачу відображати візуально кількість нових пов"язаних звернень для поточного користувача. В динамічних групах є група "!Связанные обращения", в ній показуються всі звернення данного користувача.
На даний момент бачу два варіанти вирішення задачі:
1) Створити динамічну підгрупу "Новые". Для цієї підгрупи в позиції назви динамічно показувати кількість нових звернень;
2) На головній сторінці добавити кнопку за прикладом кнопки вхідних email-ів і зав"язати на ній схожий функціонал, тільки не для email-ів, а для нових пов"язаних звернень.
Який з цих варіантів є більш прийнятним ?
Можливо знайдуться ще якісь варіанти ?
Здравствуйте.
Если нужный функционал должен выглядеть так, как Вы описали, то самое простое (не требующее конфигурирования) решение - это описанное Вами в п.1 (настроить соответствующую динамическую группу с просмотром количества записей в строке итогов).
Почав з варіанту (2).
Відразу зіткнувся з необхідністю розмістити зображення на кнопці.
Вибрав png-файл 16x16 (в інших розмірах відображається лише лівий верхній сегмент від зображення), підтягнув його на кнопку і тепер маю наступне:
- коли кнопка активна (Включить [x]), то на кнопці проявляється зображення з файлу;
- коли кнопка неактивна, то на кнопці пусто - тільки жовтий фон.
"Котенко Александр" написал:настроить соответствующую динамическую группу с просмотром количества записей в строке итогов
Цей варіант не зовсім підходить, бо він передбачає необхідність зайти в групу.
Замовник хоче, щоб на групу не треба було заходити, але щоб кількість нових пов"язаних звернень відображалася десь безпосередньо перед очима, - це і має спонукати замовника зайти на групу для роботи з цими зверненнями.
Варіант (1) в моєму викладі передбачає постійне оновлення кількості звернень в позиції назви групи, а не в ітогах.
Я її розмістив поміж кнопками
UnreadEmailCountButton і NewRemindingsCountButton
в групі NavigationButtonsControlLayout.
Включенні-виключення групи дає той же самий ефект.
Я так розумію, що є якийсь секрет в "приготуванні" файлу-зображення для кнопки, який заствляє зображення вести себе правильно, бо параметри самої кнопки співпадають з аналогічними параметрами "правильних" кнопок.
Да, сss стили :)
Заходите в консоль, далее на кнопку с лупой ("обзор элементов"), тыкайте на вашу кнопку, и посмотрите что там за стили применяются в момент нажатия. Вполне возможно, что position -161px какой нибудь устанавливается.
Там можно сразу и подредактировать и проверить эффект. Когда добьетесь своего, запоминаете название Ccs класса (вроде .base-text-edit .on-hover) который вы редактировали, созадете свой модуль, во вкладку less копируете исправленный класс, и подключаете его в define страницы: "имяМодуля!css".
А и да, еще в Diff потом в кнопку в свойство "controlConfig" нужно добавить "classes".
Я так делал, когда нужно было поменять поведения правой кнопки в текстовом контроле:
З файлу SolutionResources.xml витягнув зображення для кнопки непрочитаних email-ів (UnreadEmailCountButton) в коді Base64.
Розкодував код у файл image.png
Виявилось, таки правда, - хитро приготований файл для іконки.
По його прикладу приготував свій файл для нових пов'язаних звернень 16x64.
Ось така організація:
На сторінці [MainPage] створив нову кнопку [NewServiceRequestLinkedButton].
Добавив лічильник нових пов'язаних звернень в SQL-функцію [fn_GetContactCounters],
в [MainPageEventsProcessSchema].[PageLoadCompleteScriptTask] добавив код обробки для новоствореної кнопки у змінній [remindingTimerScript]:
"Зверев Александр" написал:То есть решение было и в правильной картинке, и в выставлении Enabled, и в выставлении стиля?
Так. Без правильної картинки при відсутності потрібних звернень картинка взагалі не відображалася.
При чому зображення не відображалося вже в самому дизайнері.
я обычно узнаю, пытаясь повторить это удаление в SQL Server Management Studio.
Тогда в тексте ошибке будет название ограничения.
По этому названию нахожу, что мешает удалению (в последней строке поставьте название ограничения):
SELECT
OBJECT_NAME (f.parent_object_id) AS [Table],
ept.value AS [Table description],
COL_NAME (fc.parent_object_id, fc.parent_column_id) AS [Column],
epc.value AS [Column description],
OBJECT_NAME (f.referenced_object_id) AS [Referenced table],
ept_ref.value AS [Referenced table description],
COL_NAME (fc.referenced_object_id, fc.referenced_column_id) AS [Referenced Column],
epc_ref.value AS [Referenced Column description],
ix.name AS [Unique referenced table],
[Unique type referenced table] =
CASE
WHEN ix.is_primary_key = 1 THEN 'Primary key'
WHEN ix.is_unique_constraint = 1 THEN 'Unique constraint'
WHEN ix.is_unique = 1 THEN 'Unique index'
END,
delete_referential_action_desc AS [Delete referential action],
update_referential_action_desc AS [Update referential action]
FROM sys.foreign_keys AS f
INNER JOIN sys.foreign_key_columns AS fc ON f.object_id = fc.constraint_object_id
INNER JOIN sys.indexes as ix ON (f.referenced_object_id = ix.object_id)
AND (f.key_index_id = ix.index_id)
LEFT JOIN sys.extended_properties AS epc ON epc.minor_id = fc.parent_column_id
AND epc.major_id = fc.parent_object_id AND epc.Name = 'MS_Description'
LEFT JOIN sys.extended_properties AS ept ON ept.minor_id = 0
AND ept.major_id = fc.parent_object_id AND ept.Name = 'MS_Description'
LEFT JOIN sys.extended_properties AS epc_ref
ON epc_ref.minor_id = fc.referenced_column_id
AND epc_ref.major_id = fc.referenced_object_id AND epc_ref.Name = 'MS_Description'
LEFT JOIN sys.extended_properties AS ept_ref ON ept_ref.minor_id = 0
AND ept_ref.major_id = f.referenced_object_id AND ept_ref.Name = 'MS_Description'
WHERE f.name = 'FKpeg4kcj9DjjyMAlGPzQ78EpM';
Ну, и на живой базе это лучше не делать
Может, есть более простой способ?
Здравствуйте.
У меня вопрос по карточке Лида.
Создал там несколько текстовых полей и все работало и я туда не заходил недели три.
А тут решил зайти и не получилось. В консоли получил ошибку
Что я могу тут поделать? Я так понимаю какаято проблема с полем Spent что я добавил, но не пойку как это устранить.
Вот новые значения в базе данных
Буду благодарен за помощь.
Я понял в чем проблема - я случайно удалил из конфигурации замещающий обьект Лида. Ех. Все по новой.
В первую очередь рекомендуется выполнить компиляцию.
В случае, если ошибка будет воспроизводиться, попбробуйте закомментировать в схеме добавление этого поля для проверки, действительно ли проблема в нем.
Более четкие рекомендации мы можем предоставить только при наличии кода схемы LeadPageV2.
Соответствие номера телефона правилам маршрутизации можно проконтролировать только при ручном вводе номера пользователем.
Например, при входящем звонке, номер записывается именно тот, который передан с АТС.
При наполнении базы посредством интеграции (например интеграция с Excel) запись происходит напрямую в базу и сервис валидации запустить не представляется возможным
Валидацию телефонных номеров, при внесении заполнении пользователем карточки либо детали можно прописать на сохранение карточки:
Перед сохранением считать требуемое значение поля и проверить, соответствует ли запись правилам маршрутизации (например 10 цифр, первая 9)
Пример реализации Вы можете посмотреть в следующих скриптах:
BasecCommunicationDetail:
this.addColumnValidator("Number", newItem.validateField, newItem);
columnName – имя колонки
validatorFn – функция валидации
newItem - само новое создаваемое entity
В BaseCommunicationViewModel
function validatorFn(emailAddress) {
var emailPattern = /^[a-zA-Z0-9._-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}$/; - Тут написать свой regex для телефонного адреса.
return emailPattern.test(emailAddress);
}
Если Вам необходимо привлечение наших разработчиков для помощи в написании кода, реализующего данный функционал, то мы можем инициировать запрос ответственному менеджеру по продаже, для обсуждения условий предоставления данной помощи.
Сообщите в техническую поддержку данные о Вашей компании, лицензии, версии и используемом Вами продукте, а также детали реализации (по каким правилам валидировать телефонные номера).
Тимур, как вы могли заметить - тема создана по конфигурации bpm'online 7.2 подозреваю, что указанный скрипт Вы не можете найти по причине того что у Вашей компании установлена версия Terrasoft 3.x.
Рекомендации по реализации на версии 3.х - во вложении
Тимур, да, такой метод в 7.2 можно использовать для валидации перед сохранением. Похожая логика используется при сохранении карточки счета.
Можно также вынести валидацию в отдельный метод и просто вызывать его в методе this.methods.save, а лучше в методе this.methods.validate, как в детали CommunicationDetail (она точно есть в версии 7.2).
Пример, который привёл Николай, больше подходит для версий 7.3 и выше.
Тимур, уточните, пожалуйста, какой результат при этом возвращает метод validate? Если деталь не должна сохраняться, метод должен возвращать false. В базовой версии при этом не происходит сохранение карточки, которая содержит деталь, а визуально карточка остаётся в режиме редактирования, и при нажатии "Отмена" данные детали "Средства связи" не будут сохранены.
Тимур, Вы правы. Происходит сохранение основной схемы, поэтому страница редактирования закрывается, но при этом значения детали "Средства связи" не сохраняются.
Для того, чтобы страница не закрывалась, можно переопределить обработчик onSaved страницы редактирования ContactPage следующим образом:
this.methods.onSaved= function(){
var saveDetailResponse = sandbox.publish("SaveDetails",
null, ["ViewModule_CardModule_Contact_detail_communications"]);if(saveDetailResponse && saveDetailResponse.cancel){return;}this.callParent(arguments);}
Для AccountPage можно создать аналогичный обработчик, заменив Contact на Account в идентификаторе модуля.
Вы пробовали включать отладчик? Какое значение переменной saveDetailResponse после публикации сообщения "SaveDetails"?
Если валидация детали реализована правильно, при попытке сохранения карточки с некорректным значением на детали "Средства связи" эта переменная должна содержать объект {cancel:true}.
у меня создан замещающий клиентский модуль на CommunicationDetail
и в случае не соответствия телефона или email то showInformationDialog выскакивает с предупреждением.
structure.userCode= function(){this.methods.validate= function(){
var Number =this.get('Number');
var communicationType =this.get('CommunicationType');switch(communicationType.value.toLowerCase()){case(ConfigurationConstants.CommunicationType.Email.toLowerCase()):if(!Ext.isEmpty(Number)){
Number = Number.trim();this.set('Number', Number);if(!new RegExp("^([a-z0-9_\\.-]+)@([a-z0-9_\\.-]+)\\.([a-z\\.]{2,6})$").test(Number)){this.showInformationDialog(resources.localizableStrings.EmailMustFormat);returnfalse;}}returntrue;case('6a3fb10c-67cc-df11-9b2a-001d60e938c6'):case('2b387201-67cc-df11-9b2a-001d60e938c6'):if(!Ext.isEmpty(Number)){
Number = Number.trim();this.set('Number', Number);if(Number.substr(0, 2)==='38'&& Number.length===2){this.set('Number', null);}elseif(!new RegExp("^380[0-9]{9}$").test(Number)){this.showInformationDialog(resources.localizableStrings.PhoneMustFormat);returnfalse;}}returntrue;default:returntrue;}};};return structure;});
С помощью sandbox.publish публикуется сообщение, на которое подписан модуль базовой детали. По этому сообщению он пытается сохранить деталь, вызывая метод валидации для каждого её элемента. Если валидация не прошла, модуль возвращает объект с одним свойством cancel, равным true.
Если в Вашем случае возвращается неопределённое значение при корректной реализации метода валидации - возможно, в Вашем случае id детали не равен "ViewModule_CardModule_Contact_detail_communications" (я проверял на базовой версии). В этом случае необходимо указать корректный id.
На bpm'online 7.5 подключили SVN (иначе было никак не создать новый пакет). И стали замечать странные вещи - вдруг оказывается, что пропадают последние изменения. И при этом Modified On поле на базе разработке у некоторых(!) схем пакета явно более старое, чем уже на сайте клиента.
Поддержка сказала, что что-то с SVN, наверное.
Подскажите, может ли SVN как-то самостоятельно восстанавливать какие-то схемы? И как заблокировать ему эту возможность?
Прошу уточнить следующее:
1. Почему без SVN не создать новый пакет?
2. После чего пропадают изменения? После выполнения какого-то действия, или после прохождения определённого периода времени?
1. При добавлении пакета было обязательное поле Version Control System Repository
2. Не удалось отследить. Причём, последний раз новые схемы полностью исчезли - пришлось их восстанаваливать по файлам
Владимир, SVN самостоятельно не может восстанавливать схемы.
Это либо паранормальное явление, либо кто-то всё же удаляет измения. Попробуйте на сутки ограничить доступ, чтобы к хранилищу могли подключиться только Вы. И проверить, будет ли наблюдаться описанная ситуация.
Но непонятен URL к которому нужно отправить запрос. А конкретно, что такое "имя прилоджения"? Где его брать? Нужно ли гдето регистрировать? Может есть более подробная документация по этой теме или примеры?
Запросы на добавление данных
Для того, чтобы добавить запись, нужно послать серверу POST запрос, указав значения колонок в теле запроса. В качестве ответа придет представление созданной Entity. Ниже создается контакт, ему проставляются значения полей Id, Name, BirthDate, Gender. Данные в обе стороны передаются в формате JSON.
Пример запроса на добавление с использованием API Sencha Touch
Запросы на обновление данных
Для обновления данных нужно послать HTTP запрос с кастомным OData-специфическим типом операции MERGE. если послать запрос с типом операции PUT, то все колонки Entity, не указанные в запросе будут заполнены своими значениями по-умолчанию.
Пример запроса на обновление с использованием API Sencha Touch
Спасибо заа примеры. Но проблема на данный момент с авторизацией.
Перепробовал уже все что на форуме нашел
1) Тут (http://www.community.terrasoft.ru/forum/topic/10573) описана проблема один в один, но я так понял, не решилась. Имя пользователя, на всякий случай, поменял на латиницу. Права на Операцию - "Доступ к Odata" есть, а вот на доступ к Объекту я не понял, как имнно установить. Но проблема скорее всего не в них.
2) Тут (http://www.community.terrasoft.ru/forum/topic/9613) описан достутп через PHP, а заодно попробовал обратится к серверу авторизации (..ServiceModel/AuthService.svc/Login). Ответ:{"Message":"Authentication failed.","StackTrace":null,"ExceptionType":"System.InvalidOperationException"}
В чем проблема, не представляю. Может еще какоето разрешение в админке требуется? Или дополнительные параметры авторизации, типа "WorkspaceName", "TimeZoneOffset", "Language"
Насчет прав доступа на объекты:
Вам нужно войти в Дизайнер системы –> Управление конфигурацией –> Конфигурация. В строке поиска ввести заголовок объекта и нажать ‘Enter’. Найти в результатах нужный объект и посмотреть его Название.
Перейти на вкладку «Администрирование: Доступ к объектам», применить фильтр по заголовку и найти нужный объект. Внизу, на вкладке «Доступ к объекту для внешних ресурсов» добавить доступ для сотрудника, под которым вы авторизируетесь.
Если нужно получить коллекцию, например Контактов, то даём права на Contact, а для обращения к коллекции добавляем слово «Collection» = «ContactCollection».
Добрый день! Возникла такая необходимость: реализовать возможность добавления второго ответственного контрагенту. Никто не сталкивался с таким?
Sales 7.5
Судя по всему, необходимо добавить деталь "Ответственные" (а вдруг потом будет 3 ответственных). И реализовать раздачу прав доступа в бизнес-процессе.
Но это будет совсем нестандартное решение
А в чем собственно сложность то? Сделайте новое поле, назовите Owner2 повесьте на список доступных значений фильтр типа Контакт.Контрагент = Наша компания, заполнение по умолчанию через объект. Доступ на основе поля как предлагал Владимир реализовать в БП...
Возникла проблема после переезда на новый билд платформы 7.3 с версии 7.3.0.2567 на
более позднюю версию 7.3.0.4021. Проблема заключается в следующем:
При квалификации лида и поиске подобных записей контактов по Name/Phone/Email не удается отобразить коллекцию записей.
Collection приходит но не отображается и возникает ошибка.
Идентифицировал появление ошибки в методе onCollectionDataLoaded в модуле
Terrasoft.controls.Grid.
onCollectionDataLoaded:function(a, b, c){ this.theoreticallyActiveRows=null; if(this.rows.length){ if(!Ext.Object.isEmpty(b)&&this.rendered){ var d =[] , a ={
rows: d };
b.each(function(a){
a =this.getRow(a);
d.push(a) } ,this); if(this.hierarchical&&(b = b.getByIndex(0).get(this.hierarchicalColumnName),
a[this.hierarchicalColumnName]=
b, "listed"===this.type&& b))
b =this.getDomRow(b),
b = parseInt(b.getAttribute("level"),10),
a.rowLevel= b +1;
b =[]; this.renderGrid(b, a); for(var a ="", e =0, f = b.length; e f; e +=1)
a += Ext.DomHelper.createHtml(b[e]);
Ext.Object.isEmpty(c)&&(c ={
mode:"bottom" }); this.addRows(a, c) } }else this.collection=this.collection|| a, this.prepareCollectionData(), this.allowRerender()&&this.reRender() }
Данные методы немного различны между версиями.
Вот данный метод из предыдущей версии из модуля grid.js:
onCollectionDataLoaded:function(collection, newItems, settings){ this.theoreticallyActiveRows=null; if(!this.rows.length){ this.collection=this.collection|| collection; this.prepareCollectionData(); var wrapEl =this.getWrapEl(); if(wrapEl &&this.allowRerender()){ this.reRender(); } return; } if(this.Ext.Object.isEmpty(newItems)||!this.rendered){ return; } var rows =[]; var options ={
rows: rows };
newItems.each(function(item){ var row =this.getRow(item);
rows.push(row); },this); if(this.hierarchical){ var firstItem = newItems.getByIndex(0); var firstItemParent = firstItem.get(this.hierarchicalColumnName);
options[this.hierarchicalColumnName]= firstItemParent; if("listed"===this.type&& firstItemParent){ var firstItemParentDom =this.getDomRow(firstItemParent); var parentLevel = parseInt(firstItemParentDom.getAttribute("level"),10);
options.rowLevel= parentLevel +1; } } var result =[]; this.renderGrid(result, options); var resultHtml =""; for(var i =0, c = result.length; i c; i +=1){
resultHtml += Ext.DomHelper.createHtml(result[i]); } if(Ext.Object.isEmpty(settings)){
settings ={
mode:"bottom" }; } this.addRows(resultHtml, settings); }
Подскажите пожалуйста, в чем может быть проблема? Вчера пол дня потратили на данную оказию.
При необходимости могу предоставить исходные материалы.
Спасибо.
Здравствуйте , есть несколько объектов Entity (родитель Базовый Объект) в которых есть каскадное \ связанное обновление реализованное на событиях. Скажите можно ли инициализировать изменения в одном из них, так чтобы для низ лежащих не проверялись права для того кто инициировал изменение в родителе.
Или вообще инициировать изменение или сохранение объекта Entity из под другого логина например?.
Права на объекты настроены на уровне записей.
Предметно:
Есть лист согласования который согласует заявление на отпуск, в котором должны поставить визы руководители и отдел кадров. У заявление на отпуск в детали есть записи указанных дней отпуска (Персональные дни), для каждого сотрудника (Контакт). В этих днях, есть кол-во использованных дней, которое по закрытие заявления рассчитываются. Права на изменение и добавление есть у отдела кадров, у сотрудника только на чтение, для того чтобы формировать заявление. Если лист согласование завизирван всеми участниками успешно то меняется заявление (изменяет состояние), и далее заявление на уровне объект (Entity) меняет те дни которые указанны в детали. И получается: чтобы всё прошло успешно - необходимо выдавать права на изменение на всё это хозяйство - всем кто должен подписать отпуск. Что не есть хорошо.
Я понимаю можно было написать update, или сделать на уровне SQL Server триггером, в первом случае придется воротить много одинаковых update со всех мест которые меняют объекты, во втором нагрузка на БД а не на IIS и условия изменения в данных не позволяют использовать триггер бд.