Files
parr_api/PARR.AIHITRelationshipsSyncer/Services/Implementations/RelationshipsSyncSrevice.cs

166 lines
7.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.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
using PARR.AIHITRelationshipsSyncer.Models;
using PARR.AIHITRelationshipsSyncer.Services.Interfaces;
using PARR.DAL.Models.Unit;
using PARR.DAL.Services.Interfaces.Unit;
using System.Reactive;
using Unit = PARR.DAL.Models.Unit.Unit;
namespace PARR.AIHITRelationshipsSyncer.Services.Implementations
{
internal class RelationshipsSyncSrevice : IRelationshipsSyncService
{
private readonly ILogger<RelationshipsSyncSrevice> logger;
private readonly IUnitService unitService;
public RelationshipsSyncSrevice(ILogger<RelationshipsSyncSrevice> logger,
IUnitService unitService
)
{
this.logger = logger;
this.unitService = unitService;
}
public async Task SyncAsync(List<AihitData> aihitdata)
{
var groupedData = aihitdata.Where(t => t.EKFindCode != null && t.ChildEk != null).GroupBy(ad => ad.EKFindCode);
//Перебираем сгруппированные по родительскому ЭК данные
foreach (var item in groupedData)
{
//Получаем имя родителя
var parentName = item.First().EKFindCode;
//if (parentName.ToLower() != "ас-рп-рцку-гор")
// continue;
//По имени получаем экземпляр Unit со всеми дочерними связями
var unit = await GetUnitByNameAsync(parentName!);
//Из данных АИХ ИТ получаем имена всех дочерних ЭК
var childsName = item.Select(t => t.ChildEk);
//Проходим циклом по полученному списку для актуализации связей в полученном нами экземпляре Unit
foreach (var childName in childsName)
{
//if (childName.ToLower() != "рпа-робин-рцку-спиуи-прочее-26-гор")
// continue;
//Ищем детей по имени
var child = unit.ChildUnits.FirstOrDefault(t => t.ChildUnit?.Name.ToLower() == childName!.ToLower().Trim());
//не нашли создаём и сразу пишем в базу, чтобы если попадуться дубликаты в списке они были созданы
if (child == null)
{
var childUnit = await GetUnitByNameAsync(childName!);
unit.ChildUnits.Add(
new UnitInUnit
{
ParentUnitId = unit.Id,
ChildUnitId = childUnit.Id,
DateCreated = DateTimeOffset.UtcNow,
DateSynced = DateTimeOffset.UtcNow
}
);
if (!await unitService.CommitAsync())
logger.LogError($"Не удалось создать связь Unit {unit.Name} с {childUnit.Name}");
else
logger.LogInformation($"----- Создана новая связь Unit {unit.Name} с {childUnit.Name} -----");
}
//Для всех обновляем дату синхронизации
else
child.DateSynced = DateTimeOffset.UtcNow;
}
//После проверки пришедших к нам из АИХ ИТ дочерних связей удаляем лишние/уже не существующие в базе
var childsToDelete = unit.ChildUnits.Where(t => childsName.All(a => t.ChildUnit?.Name != a));
if (childsToDelete.Any())
DeleteChilds(unit, childsToDelete);
//применяем изменения в базе данных
if (!await unitService.CommitAsync())
logger.LogError($"Не удалось изменить связи Unit {unit.Name}");
else
logger.LogDebug($"----- Изменены связи Unit: {unit.Name} -----");
}
//Удаляем детей у тех кого детей в выборке АИХ ИТ не оказалось
var parentNames = groupedData.Select(t => t.Key);
var units = await unitService.Get().Include(t => t.ChildUnits).ToListAsync();
var parentsToDeleteChild = units.Where(t => parentNames.All(a => t.Name != a) && t.ChildUnits.Any());
if (parentsToDeleteChild.Any())
{
foreach (var unit in parentsToDeleteChild)
{
unit.ChildUnits.Clear();
//применяем изменения в базе данных
if (!await unitService.CommitAsync())
logger.LogError($"Не удалось удалить лишние связи Unit {unit.Name}");
else
logger.LogInformation($"----- Удалены лишние связи Unit {unit.Name} -----");
}
}
}
/// <summary>
/// Удаление дочерних связей у ЭК
/// </summary>
/// <param name="unit"></param>
/// <param name="unitToDeleteChilds"></param>
private void DeleteChilds(Unit unit, IEnumerable<UnitInUnit> unitToDeleteChilds)
{
foreach (var childUnit in unitToDeleteChilds)
{
logger.LogInformation($"----- Удаление связи Unit: {childUnit.ParentUnit!.Name} - {childUnit.ChildUnit!.Name} -----");
unit.ChildUnits.Remove(childUnit);
}
}
/// <summary>
/// Создать новый ЭК по имени
/// </summary>
/// <param name="ekName"></param>
/// <returns></returns>
private async Task<Unit> CreateUnit(string ekName)
{
var unit = new Unit
{
Name = ekName.Trim()
};
if (!await unitService.CreateAsync(unit) || !await unitService.CommitAsync())
logger.LogError($"Не удалось создать Unit {unit.Name}");
else
logger.LogDebug($"----- Создан Unit: {unit.Name} -----");
return unit;
}
/// <summary>
/// Получить ЭК с дочерними связями по имени, если такого ещё нет создать
/// </summary>
/// <param name="ekName"></param>
/// <returns></returns>
private async Task<Unit> GetUnitByNameAsync(string ekName)
{
if (!unitService.Get().AsNoTracking().Any(u => u.Name.ToLower() == ekName.ToLower().Trim()))
{
return await CreateUnit(ekName);
}
return await unitService.Get()
.Include(u => u.ChildUnits)
.FirstAsync(u => u.Name.ToLower() == ekName.ToLower().Trim());
}
}
}