Files
parr_api/PARR.EsppSync/SyncService.cs
2023-11-24 16:52:56 +10:00

145 lines
6.8 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using PARR.Constants;
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
)
{
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)
{
logger.LogInformation($"Есть изменения, требуется обновление. {esppObject.TemplateName}");
SetUpdateStatus(ref template, robotConfigurationService, esppObject.Robot);
if (!await templateService.CommitAsync())
logger.LogError($"Не удалось изменить запись Template {template.Name}, Robot: {esppObject.Robot}");
else
logger.LogInformation($"Установлен принудительный статус {TaskStatusEnum.Updating}, Template {template.Name}, Robot: {esppObject.Robot}");
}//надо ли проверять если не изменился, но был статус Updating не понятно. Доверяем роботу пока, что после окончания работ он точно сообщит
else
{
logger.LogInformation($"Нет изменений, обновление не требуется. {esppObject.TemplateName}");
//если все поля совпали
//проверяем, какой был статус предыдущий статус в БД, если он был не Ок, то ставим ему ОК
var robotConfig = robotConfigurationService.GetFromTemplateByRobotCode(esppObject.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: {esppObject.Robot}");
else
logger.LogInformation($"Установлен принудительный статус {TaskStatusEnum.Ok}, Template {template.Name}, Robot: {esppObject.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;
}
}
}