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

Столкнулся со следующей проблемой.

Кейс такой нужно писать логи через NLog в очереди RabbitMQ.

Для этого использую библиотеку Nlog.RabbitMQ.Target.dll

Добавляю ее в папку MyApp\bin\ 

Затем настраиваю файлы nlog.config:

<logger name="GrayLogLogger" writeTo="grayLogAppender" minlevel="Debug" final="true" />

nlog.targets

<extensions>
        <add assembly="Nlog.RabbitMQ.Target" />
    </extensions>
    <variable name="rmqHost" value="localhost" />
    <variable name="rmqUser" value="admin" />
    <variable name="rmqPassword" value="admin" />
    <variable name="rmqvHost" value="logs" />
    <variable name="rmqvPort" value="5672" />
    <variable name="rmqExchange" value="logs" />

<target name="grayLogAppender"
                xsi:type="RabbitMQ"
                appid="CreatioDemo"
                topic="${uppercase:${level}}"
                username="${rmqUser}" 
                password="${rmqPassword}" 
                hostname="${rmqHost}" 
                exchange="${rmqExchange}"
                exchangeType="topic"
                port="${rmqvPort}"
                vhost="${rmqvHost}"
                layout="${Date} [${ThreadIdOrName}] ${uppercase:${level}} ${UserName} ${MethodName} - ${Message}"
                messageSource="nlog://${machinename}/${logger}"
                useJSON ="true">
            <field key="threadid" layout="${threadid}" />
            <field key="machinename" layout="${machinename}" />

 

при перезапуске пула конект к Rabbit создается но логи не пишуться.

Для этого нужно добавить Nlog.RabbitMQ.Target.dll в папку MyApp\Terrasoft.WebApp\bin\

И тут возникает проблема при перезапуске пула или при логине в систему:

[FileLoadException: Could not load file or assembly 'System.Threading.Tasks.Extensions, Version=4.2.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51' or one of its dependencies. The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040)]
   StackExchange.Redis.PhysicalConnection.BeginConnectAsync(LogProxy log) +0
   StackExchange.Redis.PhysicalBridge.GetConnection(LogProxy log) +461
   StackExchange.Redis.ServerEndPoint.CreateBridge(ConnectionType type, LogProxy log) +98
   StackExchange.Redis.ServerEndPoint.GetBridge(ConnectionType type, Boolean create, LogProxy log) +60
   StackExchange.Redis.ConnectionMultiplexer.ActivateAllServers(LogProxy log) +195
   StackExchange.Redis.<ReconfigureAsync>d__142.MoveNext() +7816

[AggregateException: One or more errors occurred.]
   System.Threading.Tasks.Task.ThrowIfExceptional(Boolean includeTaskCanceledExceptions) +4593189
   System.Threading.Tasks.Task.Wait(Int32 millisecondsTimeout, CancellationToken cancellationToken) +13992992
   StackExchange.Redis.ConnectionMultiplexer.ConnectImpl(Object configuration, TextWriter log) +220
   Terrasoft.Redis.StackExchangeAdapters.RedisClientsManagerAdapter..ctor(String connectionStringName, RedisConfigSection configSection) +273

 

Проверил версию  System.Threading.Tasks.Extensions в сборке Nlog.RabbitMQ.Target.dll  и ту что используется в Ceratio - совпадают.

Подскажите как можно это исправить?

Нравится

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

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

Исходя их ошибки попробуйте перезапустить redis.

Поскольку на данный момент система не поддерживает внедрение Nlog.RabbitMQ.Target.dll, то более детальной рекомендации мы дать не можем. Советую ознакомиться с этим обсуждением.

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

Всем доброго времени суток!
Столкнулся с проблемой, при сохранении Entity на событийном слое не срабатывает асинхронные операции.

Сохранение происходит в классе обработчике который подписан на очередь Rabbit

Выдает следующую ошибку:

EntityEventAsyncExecutor SendMessage - OnSavedMyEntityAsyncOperations
System.InvalidOperationException: Не удалось получить контекст выполнения фоновой операции. Для сервисов без авторизации необходимо вызвать Terrasoft.Web.Common.SessionHelper.SpecifyWebOperationIdentity.
   в Terrasoft.Core.ServiceBus.BusUtils.CreateUserContext(String userName, String sessionId, Guid externalAccessId)
   в Terrasoft.WebApp.ActorSystem.UserContextProvider.GetUserContext()
   в Terrasoft.ActorSystem.ActorReference.Tell(AppContextMessage message)
   в Terrasoft.Core.ActorSystem.Entities.EntityEventAsyncExecutor.SendMessage(Object parameters, Type operationType)

Как бороться с такой проблемой, может кто знает?

Спасибо!

Нравится

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

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

 

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

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

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

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

[Schema("Account")]
    public class Account : BaseModel
    {       
 
        [SchemaProperty("Name")]
        public string Name { get; set; }        
 
        [DetailProperty("Account")]
        public virtual List&lt;AccountWorkingTime&gt; 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 =&gt; _repository ??= new Repository
                {UserConnection = UserConnection, UseAdminRight = false};
            set =&gt; _repository = value;
        }
 
        public Models.Account GetAccountById(Guid id)
        {
            var account = Repository.GetItem&lt;Models.Account&gt;(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.<GetItems>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 для связи с разработчиками. Возможно, они подскажут по этому механизму.

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

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

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

Всем добрый день!

Столкнулся с следующей проблемой перестали выгружаться пакеты в ФС, пишет. что изменений не обнаружено. Редис чистил, пересоздавал приложение в IIS, удалял пакеты из папки Pkg в конфигурации - не помогает.

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

Нравится

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

Скорее всего включена разработка в файловой системе, когда она включена то при разратобке используется локальный статический контент (к примеру C# файлы)

Скорее всего включена разработка в файловой системе, когда она включена то при разратобке используется локальный статический контент (к примеру C# файлы)

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

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

Столкнулся с такой проблемой.

Устанавливаю пакет через CLIO - выдает ошибки - https://prnt.sc/tqkuyw

В чем может быть проблема?

Версия системы 7.16.2.1600 

 

Или может быть создать пакет в системе, вытянуть его через clio конвертировать в пакет-проект, написать нужный функционал и затем задеплоить обратно? 

Нравится

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

так же при выполнении команды clio install-gate -e dev выдает ошибки - https://prnt.sc/tqnh3s

Алексей, по первому скриншоту, похоже, дело в файловой системе Вашего ПК, не может получить доступ к определённой папке.

 

По второму, у Вас как-то получилось вместо названия объекта «7.16.2», что делать нельзя, названия должны быть с латинскими буквами и без точек. Возможно, при оформлении перепутали с версией.

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

Странно как то получается создаю новый пакет Test и сразу  пушу его в систему и выдает такое - 

https://prnt.sc/tr3etj. Тут ну никак и нигде не задается имя 7.16.

Помимо всего даже когда устанавливаю пакет через интерфейс Creatio такая же ошибка. Из-за чего так получается есть предположение?

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

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

"Вы создали пакет командой к clio?" - пакет Test да. 

 

Просто создали так?

Creating new package

To create new package project, use the next command:

 clio new-pkg &lt;PACKAGE_NAME&gt;

you can set reference on local core assembly with using Creatio file design mode with command in Pkg directory

 clio new-pkg &lt;PACKAGE_NAME&gt; -r bin

Может, что-то делали с версией?

Set package version

Set a specified package version into descriptor.json by specified package path.

clio set-pkg-version &lt;PACKAGE PATH&gt; -v &lt;PACKAGE VERSION&gt;

 

Вообще, не видя создавшегося пакета, сложно  сказать, что в нём не так.

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

просто clio new-pkg <PACKAGE_NAME>

Значит, смотреть внутрь пакета, где там упоминается «7.16.2». А падает только при установке на конкретный Ваш сайт? А если ставить на демку, то то же самое?

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

Устанавливал созданный пакет через clio на облачный дев, через интерфейс системы, стал без ошибок.

 

Значит, всё же дело не в пакете, а в сайте, куда его ставили? Может, версии отличаются?

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

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

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

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

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

Мотков Илья,

Добрый день. Я бы добавил, что есть способы достучаться из схем в функциональность Files. Через тот же ClassFactory

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

 

Ещё дополню, что все классы схем располагаются в неймспейсе Terrasoft.Configuration, если другое не задано.

 

Пакеты по сути просто папки, а конфигурация компилируется целиком, и все классы в конфигурации видны другим классам в конфигурации не зависимо от пакета.

 

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

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

Коллеги, разобрался в чем проблема... при создании нового пакета в этих папках - https://prnt.sc/u638lk генерируется текстовый файл placeholder, вот из-за него и вываливается ошибка при деплое пакета в среду, после удаления деплой прошел корректно и ошибка -

"Terrasoft.Common.InvalidNameException: Название объекта "7.16.2" некорректно" не выскакивала

Алексей, разработчики сообщили, что мы поищут способ решения этой проблемы, на текущий момент данную проблему можно обойти, указав в ConnectionStrings.config в секции tempDirectoryPath простой пусть С:\Temp

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

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

  Всем доброго времени суток! Подскажите, возможно ли использовать анонимный ws в качестве веб-хука, например для Telegram-bot?

Благодарю.

Нравится

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

1. Создаем анонимный сервис.
2. Добавляем в него метод по аналогии с HandleWebHookEvents в MandrillService:
[OperationContract]
        [WebInvoke(Method = "*", UriTemplate = "HandleWebHookEvents")]
        public void HandleWebHookEvents(Stream mandrill_events) {
}
Он принимает stream, и может ничего не возвращать. 

Как читать raw поста можно погуглить либо взять из того же метода пример.

Алексей, по поводу веб-хуков см. в этом обсуждении. Там упоминаются готовые примеры в системе и сторонних дополнениях.

1. Создаем анонимный сервис.
2. Добавляем в него метод по аналогии с HandleWebHookEvents в MandrillService:
[OperationContract]
        [WebInvoke(Method = "*", UriTemplate = "HandleWebHookEvents")]
        public void HandleWebHookEvents(Stream mandrill_events) {
}
Он принимает stream, и может ничего не возвращать. 

Как читать raw поста можно погуглить либо взять из того же метода пример.

Чтобы быстро понять, что приходить в вебхуке и как это парсить, используйте https://webhook.site/

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

Всем доброго времени суток! Столкнулся с такой проблемой. При добавлении БП в раздел "съезжает" ранее добавленная кнопка - https://prnt.sc/tn9xut.

Как с этим бороться?

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

Нравится

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

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

Вадим Косарев,

	diff: /**SCHEMA_DIFF*/[
			{
				"operation": "insert",
				"parentName": "ActionButtonsContainer",
				"propertyName": "items",
				"name": "SimpleInfoButton",
				"values": {
					"layout": { "column": 1, "row": 6, "colSpan": 1},
					"itemType": Terrasoft.ViewItemType.INFORMATION_BUTTON,
					"content": { "bindTo": "Resources.Strings.InfoButtonCaption" }
				}
			}
		]/**SCHEMA_DIFF*/,

 

Алексей, процессы открывает кнопка ProcessRunButton. Она реализована в BaseDataView (базовой схеме раздела) кодом:

{
	"operation": "insert",
	"name": "ProcessRunButton",
	"parentName": "SeparateModeActionButtonsContainer",
	"propertyName": "items",
	"values": {
		"itemType": Terrasoft.ViewItemType.BUTTON,
		"caption": {"bindTo": "Resources.Strings.RunProsessButtonCaption"},
		"imageConfig": {"bindTo": "Resources.Images.ProcessButtonImage"},
		"iconAlign": Terrasoft.controls.ButtonEnums.iconAlign.LEFT,
		"classes": {
			"imageClass": ["t-btn-image left-12px t-btn-image-left proc-btn-img-top"],
			"textClass": ["t-btn-text t-btn-left actions-button-margin-right"]
		},
		"menu": {"items": {"bindTo": "getFilteredBySectionProcesses"}},
		"visible": {"bindTo": "getIsRunProcessButtonVisible"}
	}
},

В отличие от Вашего элемента, она входит в SeparateModeActionButtonsContainer, а уже тот —в ActionButtonsContainer:

{
	"operation": "insert",
	"name": "SeparateModeActionButtonsContainer",
	"parentName": "ActionButtonsContainer",
	"propertyName": "items",
	"values": {
		"itemType": Terrasoft.ViewItemType.CONTAINER,
		"visible": {
			"bindTo": "IsCardVisible",
			"bindConfig": {
				"converter": function(value) {
					return !value;
				}
			}
		},
		"wrapClass": ["separate-action-buttons-container-wrapClass"],
		"items": []
	}
},

Возможно, Ваша кнопка с учётом иерархии контейнеров не там, где должна была находиться? Или дело в «"layout": { "column": 1, "row": 6, "colSpan": 1}», ведь нумерация идёт с нуля и 1 — это уже второй, с учётом видимой кнопки процессов?

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

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

Кто нибудь пробовал уже разрабатывать на системе ориентированной под linux?

Как там происходит разработка в ФС и отладка серверного кода, как подсоединятся к процессу и т.д., в общем весь тот процесс, что делаем на Windows?

Благодарю!

Нравится

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

Насколько понимаю, в версии на .NET Core, которая используется под Linux, сейчас возможности разработки ограничены. Там даже нет раздела «Конфигурация»:

Большинство инструментов разработки и кастомизации уже поддерживают работу на платформе .NET Core. Реализована поддержка Low-code инструментов: дизайнера процессов, мастера раздела, мастера деталей и мастера мобильного приложения.

Также поддерживают работу на платформе утилиты командной строки, которые помогают разрабатывать и автоматизировать процессы разработки: WorkspaceConsole, clio.

В процессе разработки поддержка раздела [Конфигурация]. Планируется также поддержка дизайнера объектов. Сейчас разработка этими инструментами может происходить на Windows, изменения, сделанные этими инструментами, переносятся пакетами на Linux.

Добрый день! Хотелось бы вернутся к вопросу отладки серверного кода под Linux. Спасибо!

Дмитрий Каплин,

В данном случае есть возможность провести отладку удалённо с Windows-машины. Рекомендуем использовать инструкцию ниже.

 

У вас на Linux развернут некий продукт (например по пути: '/home/user/creatioApps/Product'). В дальнейшем мы будем использовать пути, указанные для примера, у вас же будут свои пути.

 

Нужно:

1. На Linux по пути /home/user/creatioApps/Product/WorkspaceConsole/Terrasoft.Tools.WorkspaceConsole.dll.config

настраиваете конфигурационный файл, а именно соединение к базе данных, в секции <connectionStrings>.

Настройки соединения с базой данных можно скопировать с конфигурационого файла по пути /home/user/creatioApps/Product/ConnectionStrings.config

2. Для логов WorkspaceConsole на Linux создаете папку /home/user/creatioApps/Logs

3. На Linux переходите в папку /home/user/creatioApps/Product/WorkspaceConsole и запускаете следующую команду:

dotnet Terrasoft.Tools.WorkspaceConsole.dll -operation=UpdateWorkspaceSolution -workspaceName=Default -webApplicationPath="/home/user/creatioApps/Product" -confRuntimeParentDirectory="/home/user/creatioApps/Product" -logPath="/home/user/creatioApps/Logs" -autoExit=true

У Вас будут другие пути.

4. Файлы того же же продукта для Linux, который развернут на Linux, разместить на Windows (например, по пути: 'C:\Product').

Можно распаковать туда файлы из архива продукта для Linux.

5. Скопировать все файлы с Linux по пути /home/user/creatioApps/Product/Terrasoft.Configuration/Autogenerated/Src

на Windows машину по пути C:\Product\Terrasoft.Configuration\Autogenerated\Src

6. На Linux по пути /home/user/creatioApps/Product/Terrasoft.WebHost.dll.config

настраиваете конфигурационный файл, а именно меняете или добавлятете в секции  <appSettings> следующую насройку:

<add key="LoadAssemblyFromByteArray" value="false" />

Таким образом включается отладка для конфигурационной сборки.

ВНИМАНИЕ: чтобы отладка работала, среда .Net загружает сборку по прямой ссылке, однако она тогда же и блокирует перезапись этой сборки,

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

Поэтому ОТКЛЮЧАЙТЕ ОТЛАДКУ НА ПРОДУКТОВОЙ СРЕДЕ и ПЕРЕД КОМПИЛЯЦИЕЙ или УСТАНОВКОЙ ПАКЕТОВ

7. Перезапустите приложение на Linux

8. На Windows открываете проект по пути "C:\Product\Terrasoft.Configuration\Terrasoft.Configuration.Dev.csproj"

9. Подсоединяетесь к процессу на Linux, по инструкции "Удаленная отладка .NetCore приложений в Linux под Windows.pdf", которая находится во вложении.

10. Находите необходимый Вам файл в C:\Product\Terrasoft.Configuration\Autogenerated\Src и устанавливаете точку остановки.

 

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

Так же необходимо подключить vsdbg, для того чтобы MSVS могла подключиться к .net процессу. 
Install vsdbg to remote host (following script install to ~/vsdbg)
curl -sSL https://aka.ms/getvsdbgsh | bash /dev/stdin -v latest -l ~/vsdbg

Тут есть два варианта, это пересобрать docker image, включив в него вышеописанную строку.  Или каждый раз после перезапуска докера, выполнять команду:
docker exec -it curl -sSL https://aka.ms/getvsdbgsh | bash /dev/stdin -v latest -l ~/vsdbg

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

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

Павел,

Можете ознакомиться с ответом выше.

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

Всем доброго времени суток. Кто нибудь сталкивался с разработкой пользовательского виджета в аналитике. Не могу разобраться, как реализовать в виде списка? У меня есть ХП которая возвращает нужный результат. 

Можете скинуть пару примеров?

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

Нравится

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

Добрый вечер, Алексей.

 

Результат хранимой процедуры возвращайте в представление, например:

 

CREATE FUNCTION [dbo].[tsf_PathReportData]()
RETURNS @ExaminationBlocksByObject TABLE (
		[Number] nvarchar(50),
		[ExaminationId] uniqueidentifier,
		[ObjectId] uniqueidentifier,
		[MacroscopicDescription] nvarchar(max),
		[BlocksDescription] nvarchar(max))
AS
BEGIN
 
	DECLARE
		@Number nvarchar(50),
		@ExaminationId uniqueidentifier,
		@ObjectId uniqueidentifier,
		@MacroscopicDescription nvarchar(max),
		@BlocksDescription nvarchar(max)
 
	DECLARE ExaminationDetailCursor CURSOR STATIC LOCAL FOR
	SELECT
			O.Number,
			O.MacroscopicDescription,
			O.ExaminationId,
			O.Id as ObjectId
	FROM ABExaminationObject O
 
	OPEN ExaminationDetailCursor
 
	FETCH NEXT FROM ExaminationDetailCursor INTO @Number, @MacroscopicDescription, @ExaminationId, @ObjectId
 
	WHILE @@FETCH_STATUS = 0 BEGIN
 
		SET @BlocksDescription = ''
 
		SELECT @BlocksDescription = @BlocksDescription + B.Number + ' ' + B.[Description] + CHAR(13) + CHAR(10)
		FROM ABExaminationBlock B
		WHERE B.ExaminationObjectId = @ObjectId
 
		INSERT INTO @ExaminationBlocksByObject (
			Number,
			ExaminationId,
			ObjectId,
			MacroscopicDescription,
			BlocksDescription
		)
		VALUES (
			@Number,
			@ExaminationId,
			@ObjectId,
			@MacroscopicDescription,
			@BlocksDescription)
 
		FETCH NEXT FROM ExaminationDetailCursor INTO @Number, @MacroscopicDescription, @ExaminationId, @ObjectId
 
	END 
 
	CLOSE ExaminationDetailCursor 
	DEALLOCATE ExaminationDetailCursor
 
	RETURN
 
END
 
 
create view VwExaminationReport
as
select
	newid() as Id,
	Number as Number,
	MacroscopicDescription as MacroscopicDescription,
	ExaminationId as Examination,
	BlocksDescription as BlocksDescription
from [tsf_PathReportData]()

На основании этого представления создайте схему таблицы-представления в конфигурации и используйте этот объект в стандартном элементе итогов 'Список'.

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

добрый! Мне в ХП нужно передавать параметры даты из фильтров, на сколько я знаю, то представление нельзя сделать с принимаемыми параметрами.

CREATE PROCEDURE [dbo].[absp_GetProductAnalyticByZone] @startDate varchar(10), @stopDate varchar(10)
AS
SELECT 
	T.Segment [Segment], 
	ROUND(SUM(T.[AvgRevenue]), 2, 1) [AvgRevenue],
	SUM(T.[SalesCount]) [SalesCount],	
	ROUND(SUM(T.[CPA]), 2, 1) [CPA],	
	SUM(T.[SumCtr]) [SumCtr],	
	ROUND(SUM(T.[ROAS]), 2, 1) [ROAS]
FROM
	(SELECT 
		[IABZ].[Date],
		[IABZ].ZoneId,
		[IZ].Segment,
		SUM([IABZ].Ctr) [SumCtr],
		SALES_QUERY.SalesCount [SalesCount],
		SALES_QUERY.AvgRevenue [AvgRevenue],
		IIF(SALES_QUERY.SalesCount = 0 , 0,([CpcCost].[AdsCost]/SALES_QUERY.SalesCount))[CPA],
		(SALES_QUERY.SalesCount * SALES_QUERY.AvgRevenue / [CpcCost].[AdsCost]) * 100 [ROAS],
		[CpcCost].[AdsCost]
 
	FROM [InsurerAnalyticByZone] [IABZ] WITH(NOLOCK)
	LEFT OUTER JOIN [InsurerZone] [IZ] WITH(NOLOCK) ON [IABZ].ZoneId = [IZ].Id
	INNER JOIN [CpcCost] [CpcCost] WITH(NOLOCK) ON [IABZ].[Date] = [CpcCost].[Date]
	OUTER APPLY (SELECT COUNT([I].[Id]) [SalesCount],
						AVG([I].[Revenue]) [AvgRevenue]
					FROM [AbInsurance] [I] WITH(NOLOCK) 
					INNER JOIN [CityByEwa] [CBE] WITH(NOLOCK) ON [I].EwaCityId = [CBE].Id
					WHERE [I].StatusId = '195CD1AD-37B3-4F0A-B4FC-70E2BF0B3F06' 
					AND [CBE].ZoneCode = [IZ].Code 
					AND CONVERT(varchar(10), [I].CreatedAt, 120) = [IABZ].[Date]
				) SALES_QUERY
	GROUP BY [IABZ].ZoneId, [IZ].Segment, [IABZ].[Date],  [IZ].Code, [CpcCost].AdsCost, SALES_QUERY.SalesCount, SALES_QUERY.AvgRevenue	
	) AS T
WHERE T.[Date] BETWEEN @startDate AND @stopDate
GROUP BY T.ZoneId, T.Segment
 
UNION ALL 
 
SELECT 
[CBE].[Name] [Segment],
[R].[AvgRevenue] [AvgRevenue],
COUNT([I].[Id]) [SalesCount],
SUM(IIF(R.[Count] = 0, 0, [CpcCost].[AdsCost]/R.[Count])) [CPA],
 0 [SumCtr],
ROUND(SUM((R.[Count] * R.[AvgRevenue]) / [CpcCost].[AdsCost]) * 100, 2, 1) [ROAS]
FROM [AbInsurance] [I] WITH(NOLOCK) 
INNER JOIN [CityByEwa] [CBE] WITH(NOLOCK) ON [I].EwaCityId = [CBE].Id AND [CBE].Id = '9a008f3a-f865-4e74-b1f2-530f54711f2b'
INNER JOIN [CpcCost] [CpcCost] WITH(NOLOCK) ON CONVERT(varchar(10), [I].CreatedAt, 120) = [CpcCost].[Date]
OUTER APPLY ( SELECT COUNT([I].Id) [Count],
						AVG([I].[Revenue]) [AvgRevenue]
				FROM [AbInsurance] [I] WITH(NOLOCK) 
				INNER JOIN [CityByEwa] [CBE] WITH(NOLOCK) ON [I].EwaCityId = [CBE].Id AND [CBE].Id = '9a008f3a-f865-4e74-b1f2-530f54711f2b'
				INNER JOIN [CpcCost] [CpcCost] WITH(NOLOCK) ON CONVERT(varchar(10), [I].CreatedAt, 120) = [CpcCost].[Date]
				WHERE [I].StatusId = '195CD1AD-37B3-4F0A-B4FC-70E2BF0B3F06' AND CONVERT(varchar(10), [I].CreatedAt, 120) BETWEEN @startDate AND @stopDate
) R
WHERE [I].StatusId = '195CD1AD-37B3-4F0A-B4FC-70E2BF0B3F06' AND CONVERT(varchar(10), [I].CreatedAt, 120) BETWEEN @startDate AND @stopDate
GROUP BY [CBE].[Name], [R].[AvgRevenue]

вот моя ХП, возвращает мне нужную информацию

Нигрескул Алексей,

А если попробовать реализовать Ваш виджет, как наследник от базового списка итогов?

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

В чем суть архитектурного подхода micro frontend? За счет чего micro frontend позволяет быстро меняться, создавать независимые части приложения и быть командам более автономными? На эти вопросы отвечает Владислав Куварзин, Technical Leader компании Terrasoft, в своем тренинге для разработчиков. Язык видео - русский.

 

Если вам понравилось это видео из серии митапов для разработчиков TechPoint, и вы хотите смотреть новые видео в сообществе, поставьте отметку "Нравится" этой статье. Пишите о ваших впечатлениях о тренинге в комментариях.

Нравится

Поделиться

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