2023-11-22 11:37:22 +10:00
using Microsoft.Extensions.DependencyInjection ;
using Microsoft.Extensions.Logging ;
2023-11-22 12:04:33 +10:00
using PARR.Constants ;
2023-11-22 11:37:22 +10:00
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 ,
2023-11-22 12:04:33 +10:00
ConvertDbObjToComparisonObjHandlerDelegate < EsppObject > converterToEsppObject
2023-11-22 11:37:22 +10:00
)
{
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 ) ;
2024-02-28 10:17:01 +10:00
bool isChanged ;
// если в БД isActive == false, то синхронизировать только по полям из IEsppObject
if ( dbObjectInEsppObject . IsActive = = false )
{
logger . LogDebug ( $"Объект деактивирован в ПАРР. Сравниваем только обязательные поля. {esppObject.TemplateName}" ) ;
var lightDbObj = new EsppLightObject ( dbObjectInEsppObject ) ;
var lightEsppObject = new EsppLightObject ( esppObject ) ;
isChanged = IsChanged ( lightEsppObject , lightDbObj ) ;
}
else
{
logger . LogDebug ( $"Объект активирован в ПАРР. Сравниваем все поля. {esppObject.TemplateName}" ) ;
isChanged = IsChanged ( esppObject , dbObjectInEsppObject ) ;
}
2023-11-22 11:37:22 +10:00
if ( isChanged )
{
2023-11-24 16:52:56 +10:00
logger . LogInformation ( $"Есть изменения, требуется обновление. {esppObject.TemplateName}" ) ;
2023-11-22 12:04:33 +10:00
SetUpdateStatus ( ref template , robotConfigurationService , esppObject . Robot ) ;
2023-11-22 11:37:22 +10:00
if ( ! await templateService . CommitAsync ( ) )
2023-11-22 12:04:33 +10:00
logger . LogError ( $"Н е удалось изменить запись Template {template.Name}, Robot: {esppObject.Robot}" ) ;
2023-11-22 11:37:22 +10:00
else
2023-11-22 12:04:33 +10:00
logger . LogInformation ( $"Установлен принудительный статус {TaskStatusEnum.Updating}, Template {template.Name}, Robot: {esppObject.Robot}" ) ;
2023-11-22 11:37:22 +10:00
} //надо ли проверять если не изменился, но был статус Updating не понятно. Доверяем роботу пока, что после окончания работ он точно сообщит
else
{
2023-11-24 16:52:56 +10:00
logger . LogInformation ( $"Нет изменений, обновление не требуется. {esppObject.TemplateName}" ) ;
2023-11-22 11:37:22 +10:00
//если все поля совпали
//проверяем, какой был статус предыдущий статус в БД, если он был не Ок, то ставим ему О К
2023-11-22 12:04:33 +10:00
var robotConfig = robotConfigurationService . GetFromTemplateByRobotCode ( esppObject . Robot , ref template ) ;
2023-11-22 11:37:22 +10:00
if ( robotConfig . TaskStatusCode ! = ( int ) TaskStatusEnum . Ok )
{
robotConfigurationService . ChangeTaskStatus ( TaskStatusEnum . Ok , ref robotConfig ) ;
if ( ! await templateService . CommitAsync ( ) )
2023-11-22 12:04:33 +10:00
logger . LogError ( $"Н е удалось изменить запись Template {template.Name}, Robot: {esppObject.Robot}" ) ;
2023-11-22 11:37:22 +10:00
else
2023-11-22 12:04:33 +10:00
logger . LogInformation ( $"Установлен принудительный статус {TaskStatusEnum.Ok}, Template {template.Name}, Robot: {esppObject.Robot}" ) ;
2023-11-22 11:37:22 +10:00
}
}
}
}
}
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 ;
}
2024-02-28 10:17:01 +10:00
//private bool IsChanged(EsppObject esppObj, EsppObject dbObj)
private bool IsChanged ( object esppObj , object dbObj )
2023-11-22 11:37:22 +10:00
{
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 ;
}
}
}