Доброго времени суток.

Не могу сравнить два значения времени в процессе.

Задача для примера, есть ещё другие похожие задачи с этой же темой.

В текстовый параметр бизнес-процесса подставляется текст "Доброе утро", "Добрый день" и т.д. в зависимости от текущего времени. Время проверяется в соответствии с созданным справочником (унаследованный от базового), где используются колонки [Название], [Время от] (тип время) и [Время до] (тип время). Наполнение:

Доброе утро | 07:00 | 11:30

Добрый день | 11:30 | 17:30

Добрый вечер | 17:30 | 22:00

 

Что я хочу сделать: процессом Читаем данные справочника, где [Текущее время] => [Время от] И [Текущее время] < [Время до], вычитать текстовое поле Название.

В чём моя проблема: в процессе, в элементе Чтение данных, в фильтре у полей с типом Время нет параметров < = или >. Есть только = или !=, Заполнено или Не заполнено. У полей Дата/Время всё нормально есть любой вид сравнения.

Вопрос-бонус: поле с типом Время могу сравнивать только с заранее записанным Параметром процесса, а динамически указать Текущее время не могу, как это с Дата/Время указывается Текущая дата и время.

Изображение удалено.

Версия 7.13.0, Sales, Marketing, CustomerCenter Enterprise OnSite.

Нравится

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

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

 

Данную задачу можно решить через элемент "Задание-сценарий", в котором построить select или esq запрос с необходимыми Вам фильтрами. 

 

UserConnection userConnection = Get&lt;UserConnection&gt;("UserConnection");
var esq = new EntitySchemaQuery(UserConnection.EntitySchemaManager, "UsrTestLookUp");
esq.AddColumn("Name");
esq.AddColumn("UsrTimeOn");
esq.AddColumn("UsrTimeTo");
var esqTimeOnFilter = esq.CreateFilterWithParameters(FilterComparisonType.Less, "UsrTimeOn", DateTime.Now.TimeOfDay);
var esqTimeToFilter = esq.CreateFilterWithParameters(FilterComparisonType.Greater, "UsrTimeTo", DateTime.Now.TimeOfDay);
esq.Filters.Add(esqTimeOnFilter);
esq.Filters.Add(esqTimeToFilter);
EntityCollection entityCollection = esq.GetEntityCollection(UserConnection);
if (entityCollection.IsNotEmpty()) {
        foreach (var name in entityCollection) {
        	var param1 = name.GetTypedColumnValue&lt;string&gt;("Name");
        	Set ("ProcessSchemaParameter1", param1);
        }
    }
/* или через select 
var select =
    (Select)new Select(userConnection)
        .Column("Name").As("Text")
    .From("UsrTestLookUp").WithHints(Hints.NoLock)
    .Where("UsrTimeOn").IsLess(Column.Parameter(DateTime.Now.TimeOfDay))
    .And("UsrTimeTo").IsGreater(Column.Parameter(DateTime.Now.TimeOfDay));
 
string sql = select.GetSqlText();
Set ("ProcessSchemaParameter1", sql);
using (var dbExecutor = userConnection.EnsureDBConnection()) {
    using (IDataReader dataReader = select.ExecuteReader(dbExecutor)) {
        while (dataReader.Read()) {
            string Name = dataReader.GetColumnValue&lt;string&gt;("Text");
            Set ("ProcessSchemaParameter1", Name);
        }
    }
}*/
return true;

 

Заричный Антон,

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

 

Спасибо за предложенный вами вариант, он подошёл и отработал как и была поставлена задача.

Для тех, кто вдруг ещё ищет, итоговый вариант у меня получился следующим:

UserConnection userConnection = Get&lt;UserConnection&gt;("UserConnection");
var timenow = Get&lt;DateTime&gt;("CurrentTime"); // Параметр в процессе с типом Дата/Время
var esq = new EntitySchemaQuery(UserConnection.EntitySchemaManager, "TsiCCCustomerGreetingOnDaytime"); // Название справочника
esq.AddColumn("Name"); // Колонка "Название" в справочнике (где написано Добрый день/утро/вечер и т.п.)
esq.AddColumn("TsiCCCustomerGreetingTimeFrom"); // Колонка справочника Время от
esq.AddColumn("TsiCCCustomerGreetingTimeTo"); // Колонка справочника Время до
 
var esqTimeOnFilter = esq.CreateFilterWithParameters(FilterComparisonType.Less, "TsiCCCustomerGreetingTimeFrom", timenow); // Колонка справочника Время от.
var esqTimeToFilter = esq.CreateFilterWithParameters(FilterComparisonType.Greater, "TsiCCCustomerGreetingTimeTo", timenow); // Колонка справочника Время до
// В одном из двух фильтров желательно указать равенство, чтобы не было ошибок, т.е. LessOrEqual или GreaterOrEqual соответственно, в зависимости от ваших потребностей
 
esq.Filters.Add(esqTimeOnFilter);
esq.Filters.Add(esqTimeToFilter);
EntityCollection entityCollection = esq.GetEntityCollection(UserConnection);
if (entityCollection.IsNotEmpty()) {
	foreach (var name in entityCollection) {
		var paramValue = name.GetTypedColumnValue&lt;string&gt;("Name");  // Колонка "Название"
		Set ("TimeOfDayText", paramValue);  // Название параметра в процессе для записи текста сообщения
	}
}
return true;

 

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

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

 

Возврат функции модуля getView() содержит коллекцию кнопок (Terrasoft.Button) в массиве viewItems :

return this.Ext.create("Terrasoft.Container", {
                    id: "ModuleContainer",
                    selectors: {wrapEl: "#moduleContainer"},
                    classes: {wrapClassName: ["main-container-style"]},
                    items: viewItems});

Возврат функции модуля getViewModel(); В methods viewModel :

methods : {
onButtonClick: function () {
Terrasoft.showInformation("test");
}

В методе render модуля

render: function(renderTo) {
                var view = this.getView();
                var viewModel = this.getViewModel();
                view.bind(viewModel);
                view.render(renderTo);
         }

На странице создается контейнер и кнопка без реакции на клик.

Нравится

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

примеры по созданию кнопок есть в папке \Terrasoft.WebApp\Resources\ui\demo\button в конфигурации

Здравствуйте. Вцелом код выглядит правильно.

Убедитесь, что при добавлении кнопки( в diff), на событие onclick есть байндинг на ваш метод onButtonClick:

click: {bindTo: "onButtonClick"}

Demchenko Olha, Это модуль в который контент помещается на уровне объектов, то есть контент образуется при вызове вью динамически, без использования отдельной страницы вью где есть раздел diff 

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

Имею в наличии замещающую схему раздела базы знаний.

define("PortalKnowledgeBaseSection", ["HtmlEditModule", "PortalKnowledgeBaseSectionStructure", "PortalKnowledgeBaseSectionResources", "ckeditor-base", "jQuery"],
function (HtmlEditModule, structure, resources) {
    return {
        /* #region  Схема. */
        entitySchemaName: "KnowledgeBase",
        /* #endregion */
        //...
        /* #region  Методы. */
        methods: {
        //...
            /* #region  Клик по кнопке "Полноэкранный режим". */
            onFullscreenModeClick: function () {
                let control = structure;  // ok
                let schema = structure.schema;  // ok
                let rightPanel = structure.schema.rightPanel;  // ok
                // let find = structure.schema.rightPanel.find("ckeditor");  // not ok
                // let item = structure.schema.rightPanel.items[itemIndex];  // not ok
                // //перебором ищем нужный контрол по имени
                // while (item.name !== "...") {
                // ...
                // }
                let editor = $("#MyFieldHtmlEdit-html-edit"); // ok
                // htmlEdit.height(200);
                //...
                let editor = this.editor;  // not ok
                if (editor) {
                    editor.execCommand("maximize");
                }
            },
            /* #endregion */
        },
        /* #endregion */
    };
});

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

Нравится

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

Добрый день.

Я рекомендую вам использовать вместо jquery:

let editor = $("#MyFieldHtmlEdit-html-edit");

 

Нашу конструкцию, получения компонента:

var container = Ext.getCmp("MyFieldHtmlEdit")

И у данного контейнера есть свойство editor которым уже можно свободно оперировать.



Самый простой пример - зайдите на страничку редактирования KnowledgeBase и в консоль выполните следующую команду:Ext.getCmp("KnowledgeBasePageV2NotesHtmlEdit").editor.execCommand("maximize")

Григорьев Михаил Алексеевич,

Спасибо, это то, что нужно.

// KnowledgeBasePageV2NotesHtmlEdit - обычная версия 
// PortalKnowledgeBasePageNotesHtmlEdit - портальная версия
var container = Ext.getCmp("PortalKnowledgeBasePageNotesHtmlEdit")
if (container &amp;&amp; container.editor) {
  container.editor.execCommand("maximize");
}

 

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

Добрый вечер, Коллеги.

У кого-нибудь возникала на странице еще "одна страница с полями" (см. скрин внизу)

В мастере разделов нижней страницы нет.

Изображение удалено.

Нравится

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

На странице описано поле(в diff),  у которого неправильно указан родительский контейнер

Похоже на деталь "Связи". Вы делали новую страницу на основе Активности?

На странице описано поле(в diff),  у которого неправильно указан родительский контейнер

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

Как проще всего вызвать я. карты в своем модальном окне? Окно сейчас сделал по кнопке в разделе.

Карты должны вызываться отправкой запроса, подключаются так:

<head>
    <script src="https://api-maps.yandex.ru/2.1/?apikey=API-ключ&lang=ru_RU" type="text/javascript">
    </script>
</head>

для карт существует условие полной загрузки на странице DOM-элементов, контейнера куда разместится карта, перед выполнением вызова самой карты:

В качестве контейнера может использоваться любой HTML-элемент блочного типа (например, элемент div). Карта заполнит этот элемент полностью.
 
<body>
    <div id="map" style="width: 600px; height: 400px"></div>
</body>

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

Может быть знаете путь?

Нравится

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

Вопрос добавления JS по внешнему адресу обсуждался тут.

Кстати, в маркете есть несколько дополнений по работе с «Яндекс-картами», они бесплатные, можно установить и проверить, как они решили.

А ещё на днях писал о способе добавить код на все страницы.

так добавление js по внешнему адресу не подходит для решения. Код карт высылается в ответ на Get запрос с ключом к Api. Способ конечно есть. Надо создать новый визуальный модуль. В нем создать вью модель, в которой в секцию metods поместить вызов ссылки к апи по ajax. Затем можно конструкцию ymaps  использовать в дальнейшем. Во вью модель поместить свою логику работы с картами по документации Яндекса и связать со вью. Решение с маркетплейса подсказало этот ход.

 

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

https://community.terrasoft.ru/articles/prosteyshee-modalnoe-okno-modal…;

Если у Вас уже есть окно с картами и нужно открыть его как модальное, см. тут.

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

Добрый день.

Поставлена задача - регулярно пополнять раздел Продукты из прайслистов + в каждый продукт добавлять фото.

Фото хранятся 

1. в отдельных файлах (в структурированных папках) 

2. в файлах excel

3. в 1С

 

Коллеги, у кого есть опыт массовой загрузки файлов в карточки продуктов?

Спасибо.

 

Видела подобную тему двухгодичной давности ИМПОРТ ФОТО ИЗ EXCEL

Есть ли подвижки?

 

Нравится

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

Марина, стандартного решения, скорее всего, нет.

Тем более, Вы хотите загружать из трёх разнотипных мест: ФС, Excel и 1С. Для каждого нужно искать или разрабатывать свои инструменты.

 

Для файлов, проверьте возможности дополнения «File manager», там упоминается работа с галереями фото продуктов.

 

По Excel — сомневаюсь, что такое стандартно будет, нужно смотреть либо в строну встроенных скриптов на Бейсике, либо разбирать формат файла или использовать библиотеки для работы с ним. Кстати, xlsx  — это просто zip-архив, если файл переименовать и распаковать в папку, все картинки там будут.

 

С системой 1С тоже есть несколько интеграций, нужно смотреть их возможности.

 

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

Всем доброго времени суток!

Столкнулся с такой проблемой, валятся ошибки при использовании ATF.Repository объектной модели и выгрузке данных в список:

 

[Schema("Account")]
    public class Account : BaseModel
    {       
 
        [SchemaProperty("Name")]
        public string Name { get; set; }        
 
        [DetailProperty("Account")]
        public virtual List<AccountWorkingTime> WorkingTimes { get; set; }
    }
 
[Schema("AbWorkingTimeStation")]
    public class AccountWorkingTime : BaseModel
    {
        [SchemaProperty("Account")]
        public Guid AccountId { get; set; }
 
        [LookupProperty("DayOfWeek")]
        public virtual DayOfWeek DayOfWeek { get; set; }
 
        [SchemaProperty("From")]
        public DateTime From { get; set; }
 
        [SchemaProperty("To")]
        public DateTime To { get; set; }
 
    }
 
namespace PlatformIntegration.Files.cs
{
    [DefaultBinding(typeof(IAccountAdapter))]
    public class AccountAdapter : IAccountAdapter
    {
        public UserConnection UserConnection { get; set; }
 
        public AccountAdapter(UserConnection userConnection)
        {
            UserConnection = userConnection;
        }
        private IRepository _repository;
 
        private IRepository Repository
        {
            get => _repository ??= new Repository
                {UserConnection = UserConnection, UseAdminRight = false};
            set => _repository = value;
        }
 
        public Models.Account GetAccountById(Guid id)
        {
            var account = Repository.GetItem<Models.Account>(id);
            return account;
        }        
    }
}

При отработке метода GetAccountById - вылазят ошибки https://prnt.sc/uh1zso

Terrasoft.Web.Common.ServiceModel.ErrorHandler HandleError - Error getting value from 'WorkingTimes' on 'Castle.Proxies.AccountProxy'.

Newtonsoft.Json.JsonSerializationException: Error getting value from 'WorkingTimes' on 'Castle.Proxies.AccountProxy'. ---> System.Reflection.TargetInvocationException: Адресат вызова создал исключение. ---> System.InvalidCastException: Объект должен реализовывать интерфейс IConvertible.

   в System.Convert.ChangeType(Object value, Type conversionType, IFormatProvider provider)

   в ATF.Repository.Repository.FillPropertyValue[T](T model, PropertyInfo propertyInfo, Object value)

   в ATF.Repository.Repository.FillPropertyValues[T](T model, IDictionary`2 values)

   в ATF.Repository.Repository.CreateItem[T](IDictionary`2 values)

   в ATF.Repository.Repository.LoadModelByValues[T](IDictionary`2 values)

   в ATF.Repository.Repository.<>c__DisplayClass64_0`1.b__0(IDictionary`2 recordValues)

   в System.Collections.Generic.List`1.ForEach(Action`1 action)

   в ATF.Repository.Repository.GetItems[T](String filterPropertyName, Guid filterValue)

   --- Конец трассировки внутреннего стека исключений ---

   в System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor)

   в System.Reflection.RuntimeMethodInfo.UnsafeInvokeInternal(Object obj, Object[] parameters, Object[] arguments)

   в System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)

   в System.Reflection.MethodBase.Invoke(Object obj, Object[] parameters)

   в ATF.Repository.Repository.FillDetailValue[T](T model, ModelItem detail)

   в ATF.Repository.Builder.InstanceProxyHelper`1.FillProperty(IInvocation invocation, PropertyInfo property)

   в ATF.Repository.Builder.InstanceProxyHelper`1.InternalGet(IInvocation invocation, PropertyInfo property)

   в ATF.Repository.Builder.InstanceProxyHelper`1.Intercept(IInvocation invocation)

   в Castle.DynamicProxy.AbstractInvocation.Proceed()

   в Castle.Proxies.AccountProxy.get_WorkingTimes()

   в GetWorkingTimes(Object )

   в Newtonsoft.Json.Serialization.DynamicValueProvider.GetValue(Object target)

   --- Конец трассировки внутреннего стека исключений ---

   в Newtonsoft.Json.Serialization.DynamicValueProvider.GetValue(Object target)

   в Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.CalculatePropertyValues(JsonWriter writer, Object value, JsonContainerContract contract, JsonProperty member, JsonProperty property, JsonContract& memberContract, Object& memberValue)

   в Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeObject(JsonWriter writer, Object value, JsonObjectContract contract, JsonProperty member, JsonContainerContract collectionContract, JsonProperty containerProperty)

   в Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.Serialize(JsonWriter jsonWriter, Object value, Type objectType)

   в Newtonsoft.Json.JsonSerializer.SerializeInternal(JsonWriter jsonWriter, Object value, Type objectType)

   в Newtonsoft.Json.JsonConvert.SerializeObjectInternal(Object value, Type type, JsonSerializer jsonSerializer)

   в Newtonsoft.Json.JsonConvert.SerializeObject(Object value)

   в AutobookingPlatformIntegration.AccountIntegrationService.GetAccountById(Guid id)

   в SyncInvokeGetAccountById(Object , Object[] , Object[] )

   в System.ServiceModel.Dispatcher.SyncMethodInvoker.Invoke(Object instance, Object[] inputs, Object[]& outputs)

   в System.ServiceModel.Dispatcher.DispatchOperationRuntime.InvokeBegin(MessageRpc& rpc)

   в System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage5(MessageRpc& rpc)

   в System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage11(MessageRpc& rpc)

   в System.ServiceModel.Dispatcher.MessageRpc.Process(Boolean isOperationContextSet)

 

Кто нибудь сталкивался с таким поведением?



 

 

Нравится

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

Нашел в чем проблема. Не может десерелизовать в модель колонку с типом Время - https://prnt.sc/uhpw7o в DateTime. Кто работал с данным репозиторием знает решение данной проблемы?

Алексей, не вижу никаких упоминаний о ATF.Repository, кроме этой темы. Речь о тех ATF, которые сделали «.NET Core connector»? Там указан адрес на GitHub для связи с разработчиками. Возможно, они подскажут по этому механизму.

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

да, эти, писал и на почту, правда по другому вопросу, по текущему на гитхабе- пока ответа не получал

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

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

Нравится

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

Добрый день.

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

Ниже привожу пример подобной фильтрации:

if (project &amp;&amp; project.value) {
	var filterGroup = this.Terrasoft.createFilterGroup();
	var subFilters = Terrasoft.createFilterGroup();
    subFilters.addItem(Terrasoft.createColumnFilterWithParameter(
		Terrasoft.ComparisonType.EQUAL, "EWBProject", project.value));
	filterGroup.addItem(this.Terrasoft.createExistsFilter("[BTProjectDisease:BTDiseaseType:Id].Id",
		subFilters));
	var subFilters1 = Terrasoft.createFilterGroup();
	subFilters1.addItem(Terrasoft.createColumnFilterWithParameter(
		Terrasoft.ComparisonType.EQUAL, "ProjectSpecification", this.get("MasterRecordId")));
	filterGroup.addItem(this.Terrasoft.createNotExistsFilter(" 
       [SpecificationByDiseaseType:DiseaseType:Id].Id",	subFilters1));
}

В результате в базу данных сформируется такой SQL-запрос:

SELECT
	[BTDiseaseType].[Id] [Id],
	[BTDiseaseType].[Name] [Name],
	[BTDiseaseType].[BTTherapeuticAreaId] [BTTherapeuticAreaId],
	[BTTherapeuticArea].[Name] [BTTherapeuticArea.Name]
FROM
	[dbo].[BTDiseaseType] [BTDiseaseType] WITH(NOLOCK)
	LEFT OUTER JOIN [dbo].[BTTherapeuticarea] [BTTherapeuticArea] WITH(NOLOCK) ON ([BTTherapeuticArea].[Id] = [BTDiseaseType].[BTTherapeuticAreaId])
WHERE
	(EXISTS (
SELECT
	[SubBTProjectDisease].[Id] [Id]
FROM
	[dbo].[BTProjectDisease] [SubBTProjectDisease] WITH(NOLOCK)
WHERE
	[SubBTProjectDisease].[BTDiseaseTypeId] = [BTDiseaseType].[Id]
	AND [SubBTProjectDisease].[EWBProjectId] = @EWBProjectId)
AND NOT EXISTS (
SELECT
	[SubSpecificationByDiseaseType].[Id] [Id]
FROM
	[dbo].[SpecificationByDiseaseType] [SubSpecificationByDiseaseType] WITH(NOLOCK)
WHERE
	[SubSpecificationByDiseaseType].[DiseaseTypeId] = [BTDiseaseType].[Id]
	AND [SubSpecificationByDiseaseType].[ProjectSpecificationId] = @ProjectSpecificationId))
ORDER BY
	[BTTherapeuticArea.Name] DESC

 

Добрый день.

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

Ниже привожу пример подобной фильтрации:

if (project &amp;&amp; project.value) {
	var filterGroup = this.Terrasoft.createFilterGroup();
	var subFilters = Terrasoft.createFilterGroup();
    subFilters.addItem(Terrasoft.createColumnFilterWithParameter(
		Terrasoft.ComparisonType.EQUAL, "EWBProject", project.value));
	filterGroup.addItem(this.Terrasoft.createExistsFilter("[BTProjectDisease:BTDiseaseType:Id].Id",
		subFilters));
	var subFilters1 = Terrasoft.createFilterGroup();
	subFilters1.addItem(Terrasoft.createColumnFilterWithParameter(
		Terrasoft.ComparisonType.EQUAL, "ProjectSpecification", this.get("MasterRecordId")));
	filterGroup.addItem(this.Terrasoft.createNotExistsFilter(" 
       [SpecificationByDiseaseType:DiseaseType:Id].Id",	subFilters1));
}

В результате в базу данных сформируется такой SQL-запрос:

SELECT
	[BTDiseaseType].[Id] [Id],
	[BTDiseaseType].[Name] [Name],
	[BTDiseaseType].[BTTherapeuticAreaId] [BTTherapeuticAreaId],
	[BTTherapeuticArea].[Name] [BTTherapeuticArea.Name]
FROM
	[dbo].[BTDiseaseType] [BTDiseaseType] WITH(NOLOCK)
	LEFT OUTER JOIN [dbo].[BTTherapeuticarea] [BTTherapeuticArea] WITH(NOLOCK) ON ([BTTherapeuticArea].[Id] = [BTDiseaseType].[BTTherapeuticAreaId])
WHERE
	(EXISTS (
SELECT
	[SubBTProjectDisease].[Id] [Id]
FROM
	[dbo].[BTProjectDisease] [SubBTProjectDisease] WITH(NOLOCK)
WHERE
	[SubBTProjectDisease].[BTDiseaseTypeId] = [BTDiseaseType].[Id]
	AND [SubBTProjectDisease].[EWBProjectId] = @EWBProjectId)
AND NOT EXISTS (
SELECT
	[SubSpecificationByDiseaseType].[Id] [Id]
FROM
	[dbo].[SpecificationByDiseaseType] [SubSpecificationByDiseaseType] WITH(NOLOCK)
WHERE
	[SubSpecificationByDiseaseType].[DiseaseTypeId] = [BTDiseaseType].[Id]
	AND [SubSpecificationByDiseaseType].[ProjectSpecificationId] = @ProjectSpecificationId))
ORDER BY
	[BTTherapeuticArea.Name] DESC

 

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

Добрый день,

 

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

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

​
var printFormsMenuCollection = resultCollection.filterByFn(function(item) {
    return item.get("ShowInCard") === true &&(this.getFilterForReportsOrBooleanValue(item));
}, this);
 
​
getFilterForReportsOrBooleanValue(item) {
		var value = this.get("NrbPurchaseMethod");
				switch(value.displayValue) {
					case "Аукцион":
							return	item.get("Caption") === "Извещение Аукцион" || 
									item.get("Caption") === "Документация Аукцион";
				default:
							return false;
		}
},

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

Как правильно реализовать фильтрацию?

Нравится

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

Павел, а в чём проблема, если в обоих случаях будет запускаться одна и та же функция с доработками?

И initCardPrintForms, и initSectionPrintForms применяются в BaseDataView, базовой странице раздела:

/**
 * Initializes print buttons menu.
 * @protected
 * @param {Function} callback Callback function.
 * @param {Object} scope Callback function scope.
 */
initPrintButtonsMenu: function(callback, scope) {
	this.initSectionPrintForms(this.initCardPrintForms, this);
	this.initModulePrintForms(callback, scope);
},

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

{
	"operation": "insert",
	"name": "SeparateModeReportsButton",
	"parentName": "SeparateModeActionButtonsRightContainer",
	"propertyName": "items",
	"values": {
		"itemType": Terrasoft.ViewItemType.BUTTON,
		"caption": {"bindTo": "Resources.Strings.PrintButtonCaption"},
		"classes": {"wrapperClass": ["actions-button-margin-right"]},
		"controlConfig": {
			"menu": {"items": {"bindTo": "SectionPrintMenuItems"}},
			"visible": {"bindTo": "IsSectionPrintButtonVisible"}
		}
	}
},
...
{
	"operation": "insert",
	"name": "CombinedModePrintButton",
	"parentName": "CombinedModeActionButtonsCardRightContainer",
	"propertyName": "items",
	"values": {
		"itemType": Terrasoft.ViewItemType.BUTTON,
		"caption": {"bindTo": "Resources.Strings.PrintButtonCaption"},
		"classes": {"wrapperClass": ["actions-button-margin-right"]},
		"controlConfig": {"menu": {"items": {"bindTo": "CardPrintMenuItems"}}},
		"visible": {"bindTo": "IsCardPrintButtonVisible"}
	}
},

 

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

Добрый вечер.

 

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

- закрепить шапку календаря (при наличии большого количества многодневных задач шапка после прокрутки скрывается, оставаясь "сверху")

- отсортировать записи не по полю "Начало", а по полю "Завершения"

Изображение удалено.

Нравится

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

Попробовал уменьшить окно браузера.

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

 

Это компонент ядра Terrasoft.controls.ScheduleEdit, он реализован в файле https://сайт/0/core/hash/Terrasoft/controls/schedule-edit/schedule-edit…

 

Там, если смотреть HTML-код страницы, есть три блока, сверху вниз: title-area, multi-day-item-area, scroll-area. Даже по названию видно, что прокручиваться предназначен третий, с обычными задачами.

 

То есть, это код ядра, не конфигурации.

Сортировка по началу, видимо, там же:

	/**
	 * Returns the sorted list of calendar items.
	 * @private
	 * @param {Array} schedulerItemList List of calendar items.
	 * @return {Array} Sorted list of calendar items.
	 */
	sortScheduleItemList: function(schedulerItemList) {
		const sortItemList = [];
		Terrasoft.each(schedulerItemList, function(item) {
			if (!item.isMultiDayItem()) {
				sortItemList.push(item);
			}
		});
		sortItemList.sort(this.sortScheduleItemListByStartDate);
		return sortItemList;
	},
 
	/**
	 * Returns the result of comparing 2 calendar items by date.
	 * @private
	 * @param {Object} itemA Item #.
	 * @param {Object} itemB Item B.
	 * @return {Array} The result of comparing 2 calendar items by date.
	 */
	sortScheduleItemListByStartDate: function(itemA, itemB) {
		let result = 0;
		const itemAStartDate = itemA.startDate;
		const itemADuration = itemA.dueDate - itemAStartDate;
		const itemBStartDate = itemB.startDate;
		const itemBDuration = itemB.dueDate - itemBStartDate;
		if ((itemAStartDate === itemBStartDate) &amp;&amp; (itemADuration === itemBDuration)) {
			result = 0;
		} else if (itemAStartDate &gt; itemBStartDate) {
			result = 1;
		} else if (itemAStartDate &lt; itemBStartDate) {
			result = -1;
		} else if (itemADuration &gt; itemBDuration) {
			result = -1;
		} else if (itemADuration &lt; itemBDuration) {
			result = 1;
		}
		return result;
	},

 

Уточните, где именно на скриншоте у Вас скрылась шапка? И блок фильтрации, и многодневные задачи там видны.

 

Возможно, если у Вас так много в расписании многодневных задач, есть смысл применить диаграмму Ганта? Есть пара дополнений с её реализацией.

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

Вот как раз, если много задач, то при пролистывании ползунком скрывается шапка, прилагаю скриншот:

// + где настроить, чтобы  <отсортировать записи не по полю "Начало", а по полю "Завершения">/

Попробовал уменьшить окно браузера.

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

 

Это компонент ядра Terrasoft.controls.ScheduleEdit, он реализован в файле https://сайт/0/core/hash/Terrasoft/controls/schedule-edit/schedule-edit…

 

Там, если смотреть HTML-код страницы, есть три блока, сверху вниз: title-area, multi-day-item-area, scroll-area. Даже по названию видно, что прокручиваться предназначен третий, с обычными задачами.

 

То есть, это код ядра, не конфигурации.

Сортировка по началу, видимо, там же:

	/**
	 * Returns the sorted list of calendar items.
	 * @private
	 * @param {Array} schedulerItemList List of calendar items.
	 * @return {Array} Sorted list of calendar items.
	 */
	sortScheduleItemList: function(schedulerItemList) {
		const sortItemList = [];
		Terrasoft.each(schedulerItemList, function(item) {
			if (!item.isMultiDayItem()) {
				sortItemList.push(item);
			}
		});
		sortItemList.sort(this.sortScheduleItemListByStartDate);
		return sortItemList;
	},
 
	/**
	 * Returns the result of comparing 2 calendar items by date.
	 * @private
	 * @param {Object} itemA Item #.
	 * @param {Object} itemB Item B.
	 * @return {Array} The result of comparing 2 calendar items by date.
	 */
	sortScheduleItemListByStartDate: function(itemA, itemB) {
		let result = 0;
		const itemAStartDate = itemA.startDate;
		const itemADuration = itemA.dueDate - itemAStartDate;
		const itemBStartDate = itemB.startDate;
		const itemBDuration = itemB.dueDate - itemBStartDate;
		if ((itemAStartDate === itemBStartDate) &amp;&amp; (itemADuration === itemBDuration)) {
			result = 0;
		} else if (itemAStartDate &gt; itemBStartDate) {
			result = 1;
		} else if (itemAStartDate &lt; itemBStartDate) {
			result = -1;
		} else if (itemADuration &gt; itemBDuration) {
			result = -1;
		} else if (itemADuration &lt; itemBDuration) {
			result = 1;
		}
		return result;
	},

 

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

Спасибо за ответ. Возможно ли запланировать в базовой функциональности фиксацию шапки календаря и возможность настройки сортировки?

Завёл идеи о шапке многодневных и способе сортировки.

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