using AutoMapper; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using PARR.DAL.Contracts; using PARR.DAL.Models; using PARR.DAL.Services.Interfaces; using PARR.EsppTemplateSync.Domain; using PARR.EsppTemplateSync.Settings; namespace PARR.EsppTemplateSync.Services { internal class Manager : IManager { private readonly ILogger logger; private readonly IServiceProvider serviceProvider; private readonly IParserService parserService; private readonly GlobalSettings globalSettings; private readonly IMapper mapper; public Manager( ILogger logger, IServiceProvider serviceProvider, IParserService parserService, GlobalSettings globalSettings, IMapper mapper ) { this.logger = logger; this.serviceProvider = serviceProvider; this.parserService = parserService; this.globalSettings = globalSettings; this.mapper = mapper; } public Task ManageFileAsync(string path) { throw new NotImplementedException(); } public async Task ManageStringAsync(string str) { // тут обязательно нужна проверка, если str не того формата, возникает exception в ParseStringAsync if (string.IsNullOrEmpty(str)) return; var esppTemplate = parserService.ParseString(str); if (esppTemplate == null) { return; } else { //если шаблон не аквтивен, пропускаем //if (!esppTemplate.IsActive) //{ // return isSuccess; //} await SyncTemplateAsync(esppTemplate); } return; } private async Task SyncTemplateAsync(EsppTemplate esppTemplate) { using (var scope = serviceProvider.CreateScope()) { var services = scope.ServiceProvider; var templateService = services.GetService(); if (templateService == null) throw new Exception($"Не найден сервис: {nameof(ITemplateService)}"); var robotConfigurationService = services.GetService(); if (robotConfigurationService == null) throw new Exception($"Не найден сервис: {nameof(IRobotConfigurationService)}"); Template? template = await templateService.GetTemplateByNameAsync(esppTemplate.Name); //существует в ЕСПП но отсутствует в ПАРР. //TODO деактивируем и видимо ещё что-то нужно if (template == null) { // создает запись-шаблон из ЕСПП в ПАРР. Возможно избыточно так как эталон в ПАРР ////esppTemplate.StatusCode = "Deactivating"; ////--- //esppTemplate.StatusCode = (int)StatusTemplateEnum.Ok; //esppTemplate.IsActive = false; //if (!await templateService.CreateAsync(esppTemplate) || !await templateService.CommitAsync()) //{ // logger.LogError($"Не удалось создать запись Template {esppTemplate.Name}({esppTemplate.ShortDescription})"); //} //else // logger.LogInformation($"----- Создана запись Template {esppTemplate.Name}({esppTemplate.ShortDescription}) -----"); //--- logger.LogWarning($"----- Найден шаблон ЕСПП незарегистрированный в ПАРР {esppTemplate.Name}({esppTemplate.ShortDescription}) -----"); return; } else { var mappedTemplate = mapper.Map(template); if (mappedTemplate == null) return; var isChanged = IsChanged(mappedTemplate, esppTemplate); if (isChanged) { SetUpdateStatus(template, robotConfigurationService); if (!await templateService.CommitAsync()) logger.LogError($"Не удалось изменить запись Template {template.Name}"); else logger.LogInformation($"----- Установлен принудительный статус {TaskStatusEnum.Updating.ToString()} Template {template.Name} -----"); } //надо ли проверять если не изменился, но был статус Updating не понятно. Доверяем роботу пока, что после окончания работ от точно сообщит else { //если все поля совпали //проверяем, какой был статус у шаблона, если он был не Ок, то ставим ему ОК var robotConfig = robotConfigurationService.GetFromTemplateByRobotCode(RobotsEnum.TemplateOrder, ref template); if (robotConfig.TaskStatusCode != (int)TaskStatusEnum.Ok) { robotConfigurationService.ChangeTaskStatus(TaskStatusEnum.Ok, ref robotConfig); if (!await templateService.CommitAsync()) logger.LogError($"Не удалось изменить запись Template {template.Name}"); else logger.LogInformation($"----- Установлен принудительный статус {TaskStatusEnum.Ok.ToString()} Template {template.Name} -----"); } } } } return; } private void SetUpdateStatus(Template template, IRobotConfigurationService robotConfigurationService) { var robotConfig = robotConfigurationService.GetFromTemplateByRobotCode(RobotsEnum.TemplateOrder, ref template); robotConfigurationService.ChangeTaskStatus(TaskStatusEnum.Updating, ref robotConfig); } private bool IsChanged(EsppTemplate template, EsppTemplate esppTemplate) { foreach (var prop in template.GetType().GetProperties()) { if (prop == null) continue; if (globalSettings.IgnoreTemplateFields != null && globalSettings.IgnoreTemplateFields.Contains(prop.Name)) continue; var parrValue = template.GetType().GetProperty(prop.Name)?.GetValue(template, null); var esppValue = esppTemplate.GetType().GetProperty(prop.Name)?.GetValue(esppTemplate, null); if (parrValue == null || esppValue == null) continue; //Replace("\r","").Replace("\n","") - в подробном описании могут быть переносы строк, в Rabbit прилетает без переносов. Убираем переносы для стравнения var parrValueStr = parrValue!.ToString()!.ToLower().Replace("\r", "").Replace("\n", ""); var esppValueStr = esppValue!.ToString()!.ToLower(); if (parrValueStr != esppValueStr) { logger.LogDebug($"Не совпадают поля. parrValueStr: {parrValueStr}, esppValueStr: {esppValueStr}"); return true; } } return false; } } }