Files
parr_api/PARR.AIHITMainSyncer/Services/SyncerService.cs

218 lines
8.3 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.Logging;
using PARR.BLL.Domain.Mq;
using PARR.BLL.Services.Interfaces;
using PARR.DAL.Extensions;
using PARR.DAL.Models.Unit;
using PARR.DAL.Services.Interfaces.Unit;
namespace PARR.AIHITMainSyncer.Services
{
internal class SyncerService : ISyncerService
{
private readonly ILogger<SyncerService> logger;
private readonly ITransformService transformService;
private readonly IUnitService unitService;
private readonly IUnitFieldService unitFieldService;
private readonly IUnitFieldValueService unitFieldValueService;
public SyncerService(
ILogger<SyncerService> logger,
ITransformService transformService,
IUnitService unitService,
IUnitFieldService unitFieldService,
IUnitFieldValueService unitFieldValueService
)
{
this.logger = logger;
this.transformService = transformService;
this.unitService = unitService;
this.unitFieldService = unitFieldService;
this.unitFieldValueService = unitFieldValueService;
}
public async Task SyncAsync(string msg)
{
logger.LogInformation("Запуск синхронизации данных из очереди сообщений в ПАРР.");
var objFromQuery = transformService.GetModelFromJson<AihitMainDataMq>(msg);
if (objFromQuery == null)
return;
await SyncUnitAsync(objFromQuery);
}
private async Task SyncUnitAsync(AihitMainDataMq objFromQuery)
{
var isChanged = false;
var unit = await unitService.GetByName(objFromQuery.Name);
foreach (var item in objFromQuery.Properties)
{ //актуализируем справочники в соответствии с пришедшими данными
var field = await CreateUnitFieldIfNotExistAsync(item.Key);
var value = await CreateFieldValueIfNotExistAsync(field, item.Value);
//Если ЭК не найден то создаём его
if (unit == null)
unit = await CreateUnitAsync(objFromQuery);
//else
// logger.LogDebug($"Найден Unit в БД: {unit.Name})");
//теперь проверяем наличие поля связанного с этим ЭК
if (SyncFields(unit, field) && !isChanged)
isChanged = true;
//Синхронизируем значение
if (SyncValues(unit, field, value) && !isChanged)
isChanged = true;
}
if (isChanged && !await unitService.CommitAsync())
logger.LogError($"Не удалось изменить Unit {objFromQuery.Name}");
else
logger.LogDebug($"----- Набор данных в Unit изменён: {objFromQuery.Name} -----");
}
private bool SyncFields(Unit unit, UnitField field)
{
var isChanged = false;
var fieldInUnit = unit!.UnitFields.FirstOrDefault(u => u.FieldId == field.Id);
if (fieldInUnit == null)
{
if (!isChanged) isChanged = true;
unit.UnitFields.Add(
new UnitInField { UnitId = unit.Id, FieldId = field.Id, DateCreated = DateTimeOffset.UtcNow }
);
}
return isChanged;
}
private bool SyncValues(Unit unit, UnitField field, UnitFieldValue value)
{
var isChanged = false;
var valueInUnit = unit!.UnitValues.FirstOrDefault(uv => uv.FieldId == field.Id);
if (valueInUnit == null)
{
if (!isChanged) isChanged = true;
unit.UnitValues.Add(
new UnitInValue
{
UnitId = unit.Id,
FieldId = field.Id,
ValueId = value.Id,
DateCreated = DateTime.UtcNow
}
);
}
else if (valueInUnit.Value != value)
{
if (!isChanged) isChanged = true;
{
valueInUnit.ValueId = value.Id;
valueInUnit.DateModified = DateTime.UtcNow;
}
}
return isChanged;
}
private async Task<Unit> CreateUnitAsync(AihitMainDataMq objFromQuery)
{
var unit = new Unit { Name = objFromQuery.Name.Trim() };
if (!await unitService.CreateAsync(unit) || !await unitService.CommitAsync())
logger.LogError($"Не удалось создать Unit {unit.Name}");
else
logger.LogDebug($"----- Создан Unit: {unit.Name} -----");
return (await unitService.GetByName(unit.Name))!;
}
private async Task<UnitField> CreateUnitFieldIfNotExistAsync(string name)
{
var existUnitField = await unitFieldService.GetByAihitNameAsync(name);
if (existUnitField != null)
return existUnitField;
var field = new UnitField
{
Id = Guid.NewGuid(),
AihitName = name.Trim(),
EsppName = null,
};
if (!await unitFieldService.CreateAsync(field) || !await unitFieldService.CommitAsync())
logger.LogError($"Не удалось создать запись в таблице Fields: {name}, {field.ToJson()}");
else
logger.LogDebug($"Создана запись а таблице Fields: {name}, {field.ToJson()}");
return (await unitFieldService.GetAsync(field.Id))!;
}
private async Task<UnitFieldValue> CreateFieldValueIfNotExistAsync(UnitField field, string? value)
{
var existUnitFieldValue = await unitFieldValueService.GetByValueNameAsync(value);
//если значение существует отдаем его
if (existUnitFieldValue != null)
{
//проверяем связь с таблицей Fields
if (existUnitFieldValue.FieldValues.FirstOrDefault(fv => fv.FieldId == field.Id) == null)
{
var unitFieldInUnitFieldValue = new UnitFieldInUnitFieldValue
{
FieldId = field.Id,
FieldValueId = existUnitFieldValue.Id,
DateCreated = DateTime.UtcNow,
};
existUnitFieldValue.FieldValues.Add(unitFieldInUnitFieldValue);
if (!await unitFieldValueService.CommitAsync())
logger.LogError($"Не удалось создать связь таблицы FieldValues и Fields: {unitFieldValueService.ToJson()}");
else
logger.LogDebug($"Создана связь таблицы FieldValues и Fields: {unitFieldValueService.ToJson()}");
}
return existUnitFieldValue;
}
//значение не найдено значит создаём его
var newValue = new UnitFieldValue
{
Id = Guid.NewGuid(),
Value = (value == null) ? null : value.Trim()
};
//и привязываем значение к полю
newValue.FieldValues.Add(
new UnitFieldInUnitFieldValue
{
FieldId = field.Id,
FieldValueId = newValue.Id,
DateCreated = DateTime.UtcNow,
}
);
//пишем в базу данных
if (!await unitFieldValueService.CreateAsync(newValue) || !await unitFieldValueService.CommitAsync())
logger.LogError($"Не удалось создать запись в таблице Values: {newValue.Value}, {newValue.ToJson()}");
else
logger.LogDebug($"Создана запись а таблице Values: {newValue.Value}, {newValue.ToJson()}");
return (await unitFieldValueService.GetAsync(newValue.Id))!;
}
}
}