feat(EsppSync): общая логика для синхронизации шаблонов и расписаний

This commit is contained in:
Mikhail Trubnikov
2023-11-22 11:37:22 +10:00
parent c88f7f2731
commit fffdb134c6
8 changed files with 206 additions and 7 deletions

View File

@@ -0,0 +1,140 @@
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using PARR.DAL.Contracts;
using PARR.DAL.Models;
using PARR.DAL.Services.Interfaces;
namespace PARR.EsppSync
{
internal class SyncService<EsppObject> : ISyncService<EsppObject> where EsppObject : class, IEsppObject
{
private readonly ILogger<SyncService<EsppObject>> logger;
private readonly IServiceProvider serviceProvider;
public SyncService(
ILogger<SyncService<EsppObject>> logger,
IServiceProvider serviceProvider
)
{
this.logger = logger;
this.serviceProvider = serviceProvider;
}
public async Task SyncEsppObjectAsync(
string str,
ParserHandlerDelegate<EsppObject> parser,
ConvertDbObjToComparisonObjHandlerDelegate<EsppObject> converterToEsppObject,
RobotsEnum robot
)
{
logger.LogDebug($"Получил строку. Начинаю работать. Строка: {str}");
if (string.IsNullOrEmpty(str))
{
logger.LogWarning("Получил пустую строку, ничего не делаю.");
return;
}
var esppObject = parser.Invoke(str);
if (esppObject == null)
{
logger.LogWarning("После парсинга строки, esppObject = null. Дальше ничего не буду делать.");
return;
}
using (var scope = serviceProvider.CreateScope())
{
var templateService = GetServiceInScope<ITemplateService>(scope);
var robotConfigurationService = GetServiceInScope<IRobotConfigurationService>(scope);
var template = await templateService.GetTemplateByNameAsync(esppObject.TemplateName);
//todo: существует в ЕСПП но отсутствует в ПАРР. Может его деактивировать или еще что-то сделать. Пока просто пропустим
if (template == null)
{
logger.LogWarning($"Найден объект в ЕСПП с именем шаблона {esppObject.TemplateName} незарегистрированный в ПАРР.");
return;
}
else
{
var dbObjectInEsppObject = converterToEsppObject.Invoke(template);
var isChanged = IsChanged(esppObject, dbObjectInEsppObject);
if (isChanged)
{
SetUpdateStatus(ref template, robotConfigurationService, robot);
if (!await templateService.CommitAsync())
logger.LogError($"Не удалось изменить запись Template {template.Name}, Robot: {robot}");
else
logger.LogInformation($"Установлен принудительный статус {TaskStatusEnum.Updating}, Template {template.Name}, Robot: {robot}");
}//надо ли проверять если не изменился, но был статус Updating не понятно. Доверяем роботу пока, что после окончания работ он точно сообщит
else
{
//если все поля совпали
//проверяем, какой был статус предыдущий статус в БД, если он был не Ок, то ставим ему ОК
var robotConfig = robotConfigurationService.GetFromTemplateByRobotCode(robot, ref template);
if (robotConfig.TaskStatusCode != (int)TaskStatusEnum.Ok)
{
robotConfigurationService.ChangeTaskStatus(TaskStatusEnum.Ok, ref robotConfig);
if (!await templateService.CommitAsync())
logger.LogError($"Не удалось изменить запись Template {template.Name}, Robot: {robot}");
else
logger.LogInformation($"Установлен принудительный статус {TaskStatusEnum.Ok}, Template {template.Name}, Robot: {robot}");
}
}
}
}
}
private void SetUpdateStatus(ref Template template, IRobotConfigurationService robotConfigurationService, RobotsEnum robot)
{
var robotConfig = robotConfigurationService.GetFromTemplateByRobotCode(robot, ref template);
robotConfigurationService.ChangeTaskStatus(TaskStatusEnum.Updating, ref robotConfig);
}
private Service GetServiceInScope<Service>(IServiceScope scope)
{
var service = scope.ServiceProvider.GetService<Service>();
if (service == null)
throw new Exception($"Не найден сервис: {nameof(Service)}");
return service;
}
private bool IsChanged(EsppObject esppObj, EsppObject dbObj)
{
foreach (var prop in dbObj.GetType().GetProperties())
{
if (prop == null)
continue;
var dbValue = dbObj.GetType().GetProperty(prop.Name)?.GetValue(dbObj, null);
var esppValue = esppObj.GetType().GetProperty(prop.Name)?.GetValue(esppObj, null);
if (dbValue == null || esppValue == null)
continue;
//Replace("\r","").Replace("\n","") - в подробном описании могут быть переносы строк, в Rabbit прилетает без переносов. Убираем переносы для стравнения
var dbValueStr = dbValue!.ToString()!.ToLower().Replace("\r", "").Replace("\n", "");
var esppValueStr = esppValue!.ToString()!.ToLower();
if (dbValueStr != esppValueStr)
{
logger.LogDebug($"Не совпадают поля. dbValueStr: {dbValueStr}, esppValueStr: {esppValueStr}");
return true;
}
}
return false;
}
}
}