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 logger; private readonly ITransformService transformService; private readonly IUnitService unitService; private readonly IUnitFieldService unitFieldService; public SyncerService( ILogger logger, ITransformService transformService, IUnitService unitService, IUnitFieldService unitFieldService ) { this.logger = logger; this.transformService = transformService; this.unitService = unitService; this.unitFieldService = unitFieldService; } public async Task SyncAsync(string msg) { logger.LogInformation("Запуск синхронизации данных из очереди сообщений в ПАРР."); var objFromQuery = transformService.GetModelFromJson(msg); if (objFromQuery == null) return; await SyncUnitAsync(objFromQuery); } private async Task SyncUnitAsync(AihitMainDataMq objFromQuery) { var fields = await GetFieldsInObjectAsync(objFromQuery); var unit = await unitService.GetUnitWithFieldsAsync(objFromQuery.Name); if (unit == null) unit = await CreateUnitAsync(objFromQuery); else logger.LogDebug($"Найден Unit в БД: {unit.Name})"); await SyncFieldInUnitAsync(unit!, fields); } private async Task SyncFieldInUnitAsync(Unit unit, List fieldsId) { var isChanged = false; //Смотрим какие поля нам прислали, есть новые? var newFields = fieldsId.Except(unit.UnitFields.Select(uf => uf.FieldId)).ToList(); //добавляем если есть if (newFields.Any()) { if (!isChanged) isChanged = true; newFields.ForEach(uf => { unit.UnitFields.Add( new UnitInField { UnitId = unit.Id, FieldId = uf, DateCreated = DateTimeOffset.UtcNow } ); }); } //TODO: Удаление неактуальных if (isChanged && !await unitFieldService.CommitAsync()) logger.LogError($"Не удалось изменить набор Fields в Unit {unit.Name}"); else logger.LogInformation($"----- Набор Fields в Unit изменён: {unit.Name} -----"); } private async Task> GetFieldsInObjectAsync(AihitMainDataMq objFromQuery) { var fields = new List(); foreach (var item in objFromQuery.Properties) { var field = await CreateUnitFieldIfNotExistAsync(item.Key); fields.Add(field!.Id); } return fields; } private async Task 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.LogInformation($"----- Создан Unit: {unit.Name} -----"); return await unitService.GetUnitWithFieldsAsync(unit.Name); } private async Task 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.LogInformation($"Создана запись а таблице Fields: {name}, {field.ToJson()}"); return await unitFieldService.GetAsync(field.Id); } } }