feat(EsppSync): общая логика для синхронизации шаблонов и расписаний
This commit is contained in:
@@ -51,7 +51,9 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PARR.EsppApi", "PARR.EsppAp
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PARR.Test", "PARR.Test\PARR.Test.csproj", "{CFE2A198-67BF-4828-8E8D-31A01858FDA7}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PARR.Constants", "PARR.Constants\PARR.Constants.csproj", "{46B09885-C9FB-449C-ACAA-24C671194C4D}"
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PARR.Constants", "PARR.Constants\PARR.Constants.csproj", "{46B09885-C9FB-449C-ACAA-24C671194C4D}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PARR.EsppSync", "PARR.EsppSync\PARR.EsppSync.csproj", "{71121EF7-D4C1-43A4-9243-EF5C4C82030F}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
@@ -141,6 +143,10 @@ Global
|
||||
{46B09885-C9FB-449C-ACAA-24C671194C4D}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{46B09885-C9FB-449C-ACAA-24C671194C4D}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{46B09885-C9FB-449C-ACAA-24C671194C4D}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{71121EF7-D4C1-43A4-9243-EF5C4C82030F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{71121EF7-D4C1-43A4-9243-EF5C4C82030F}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{71121EF7-D4C1-43A4-9243-EF5C4C82030F}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{71121EF7-D4C1-43A4-9243-EF5C4C82030F}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
||||
7
PARR.EsppSync/IEsppObject.cs
Normal file
7
PARR.EsppSync/IEsppObject.cs
Normal file
@@ -0,0 +1,7 @@
|
||||
namespace PARR.EsppSync
|
||||
{
|
||||
public interface IEsppObject
|
||||
{
|
||||
public string TemplateName { get; set; }
|
||||
}
|
||||
}
|
||||
26
PARR.EsppSync/ISyncService.cs
Normal file
26
PARR.EsppSync/ISyncService.cs
Normal file
@@ -0,0 +1,26 @@
|
||||
using PARR.DAL.Contracts;
|
||||
using PARR.DAL.Models;
|
||||
|
||||
namespace PARR.EsppSync
|
||||
{
|
||||
/// <summary>
|
||||
/// Делегат парсинга из строки в модель EsppObject
|
||||
/// </summary>
|
||||
/// <typeparam name="EsppObject"></typeparam>
|
||||
/// <param name="str"></param>
|
||||
/// <returns></returns>
|
||||
public delegate EsppObject ParserHandlerDelegate<EsppObject>(string str) where EsppObject : class, IEsppObject;
|
||||
|
||||
/// <summary>
|
||||
/// Конвертирует Template в модель для сравнения
|
||||
/// </summary>
|
||||
/// <typeparam name="EsppObject"></typeparam>
|
||||
/// <param name="templateName"></param>
|
||||
/// <returns></returns>
|
||||
public delegate EsppObject ConvertDbObjToComparisonObjHandlerDelegate<EsppObject>(Template template) where EsppObject : class, IEsppObject;
|
||||
|
||||
public interface ISyncService<EsppObject> where EsppObject : class, IEsppObject
|
||||
{
|
||||
Task SyncEsppObjectAsync(string str, ParserHandlerDelegate<EsppObject> parser, ConvertDbObjToComparisonObjHandlerDelegate<EsppObject> converterToEsppObject, RobotsEnum robot);
|
||||
}
|
||||
}
|
||||
17
PARR.EsppSync/PARR.EsppSync.csproj
Normal file
17
PARR.EsppSync/PARR.EsppSync.csproj
Normal file
@@ -0,0 +1,17 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="7.0.1" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\PARR.DAL\PARR.DAL.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
140
PARR.EsppSync/SyncService.cs
Normal file
140
PARR.EsppSync/SyncService.cs
Normal 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;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -116,9 +116,9 @@ namespace PARR.EsppTemplateSync.Services
|
||||
if (!await templateService.CommitAsync())
|
||||
logger.LogError($"Не удалось изменить запись Template {template.Name}");
|
||||
else
|
||||
logger.LogInformation($"----- Установлен принудительный статус {TaskStatusEnum.Updating.ToString()} Template {template.Name} -----");
|
||||
logger.LogInformation($"----- Установлен принудительный статус {TaskStatusEnum.Updating} Template {template.Name} -----");
|
||||
|
||||
} //надо ли проверять если не изменился, но был статус Updating не понятно. Доверяем роботу пока, что после окончания работ от точно сообщит
|
||||
} //надо ли проверять если не изменился, но был статус Updating не понятно. Доверяем роботу пока, что после окончания работ он точно сообщит
|
||||
else
|
||||
{
|
||||
//если все поля совпали
|
||||
@@ -151,9 +151,11 @@ namespace PARR.EsppTemplateSync.Services
|
||||
{
|
||||
foreach (var prop in template.GetType().GetProperties())
|
||||
{
|
||||
if (prop == null) continue;
|
||||
if (prop == null)
|
||||
continue;
|
||||
|
||||
if (globalSettings.IgnoreTemplateFields != null && globalSettings.IgnoreTemplateFields.Contains(prop.Name)) 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);
|
||||
|
||||
@@ -119,7 +119,7 @@ namespace PARR.EsppTemplateSync.Services
|
||||
}
|
||||
|
||||
|
||||
// dll
|
||||
//// dll
|
||||
|
||||
//public delegate Dt CustomParserHandlerDelegate<Dt>(string str);
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
- PARR.EsppOrderLoaderWorker
|
||||
- PARR.EsppOrderManager - управление нарядами в ЕСПП (в работу, выполнить, и т.п.)
|
||||
- PARR.EsppOrderManagerWorker
|
||||
- PARR.EsppSync - общая логика синхронизации шаблонов и расписаний ЕСПП с БД PARR
|
||||
- PARR.EsppTemplateSync - логика синхронизации шаблонов ESPP с БД PARR
|
||||
- PARR.EsppTemplateSyncWorker - worker для PARR.EsppTemplateSync
|
||||
- PARR.GeneratorTemplates - логика генерации шаблонов в ПАРР
|
||||
|
||||
Reference in New Issue
Block a user