From 9387b7951c80dfea00feb962e51636ed7d73ea88 Mon Sep 17 00:00:00 2001 From: Mikhail Kuznetsov Date: Mon, 19 Jan 2026 11:46:25 +1000 Subject: [PATCH] =?UTF-8?q?feat(esppScheduleSync):=20=D0=B4=D0=BE=D0=B1?= =?UTF-8?q?=D0=B0=D0=B2=D0=BB=D0=B5=D0=BD=D0=BE=20=D0=B6=D1=83=D1=80=D0=BD?= =?UTF-8?q?=D0=B0=D0=BB=D0=B8=D1=80=D0=BE=D0=B2=D0=B0=D0=BD=D0=B8=D0=B5=20?= =?UTF-8?q?=D1=80=D0=B0=D1=81=D0=BF=D0=B8=D1=81=D0=B0=D0=BD=D0=B8=D0=B9=20?= =?UTF-8?q?=D0=B8=D0=BC=D0=B5=D1=8E=D1=89=D0=B5=20=D1=80=D0=B0=D1=81=D1=85?= =?UTF-8?q?=D0=BE=D0=B6=D0=B4=D0=B5=D0=BD=D0=B8=D0=B5=20=D1=81=20=D0=B1?= =?UTF-8?q?=D0=B0=D0=B7=D0=BE=D0=B9=20=D0=B8=20=D0=BF=D0=BE=D1=82=D0=B5?= =?UTF-8?q?=D0=BD=D1=86=D0=B8=D0=B0=D0=BB=D1=8C=D0=BD=D0=BE=20=D0=BF=D0=BE?= =?UTF-8?q?=D1=82=D0=B5=D1=80=D1=8F=D0=BD=D0=BD=D1=8B=D0=B5=20=D1=88=D0=B0?= =?UTF-8?q?=D0=B1=D0=BB=D0=BE=D0=BD=D1=8B.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- PARR.EsppScheduleSync/ScheduleSyncher.cs | 104 ++++++++++++++++++++++- 1 file changed, 103 insertions(+), 1 deletion(-) diff --git a/PARR.EsppScheduleSync/ScheduleSyncher.cs b/PARR.EsppScheduleSync/ScheduleSyncher.cs index 2f104924..1d47c10e 100644 --- a/PARR.EsppScheduleSync/ScheduleSyncher.cs +++ b/PARR.EsppScheduleSync/ScheduleSyncher.cs @@ -1,4 +1,5 @@ -using Microsoft.Extensions.DependencyInjection; +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using PARR.BLL.Helpers; using PARR.BLL.Services.Interfaces; @@ -68,6 +69,107 @@ namespace PARR.EsppScheduleSync private async Task SyncScheduleAsync(string str) { + const int expectedParts = 24; + var separator = globalSettings.ParsingSeparator; + + var parts = str.Split(separator); + if (parts.Length != expectedParts) + { + logger.LogWarning("Некорректное количество полей в строке расписания: {Actual} (ожидается {Expected})", parts.Length, expectedParts); + await syncService.SyncEsppObjectAsync(str, ParseStrToEsppObject, ConvertDbObjToEsppObj); + return; + } + + var esppScheduleId = parts[0]; // ScheduleEsppId из ЕСПП + var templateNameRaw = parts[6]; + var templateName = templateNameRaw.ToUpper(); + + // Проверка префикса (как в ParseStrToEsppObject) + if (string.IsNullOrEmpty(settingsFromDb.TemplatePrefixWithoutVariable) || + !templateName.Contains(settingsFromDb.TemplatePrefixWithoutVariable)) + { + logger.LogWarning("Имя шаблона '{TemplateName}' не соответствует префиксу '{Prefix}'. Пропущено.", templateName, settingsFromDb.TemplatePrefixWithoutVariable); + await syncService.SyncEsppObjectAsync(str, ParseStrToEsppObject, ConvertDbObjToEsppObj); + return; + } + + // === ЕДИНЫЙ ЗАПРОС: ищем по имени ИЛИ по ScheduleEsppId === + using var scope = serviceProvider.CreateScope(); + var templateService = scope.ServiceProvider.GetRequiredService(); + + var candidates = await templateService.Get() + .Where(t => t.Name == templateName || t.ScheduleEsppId == esppScheduleId) + .ToListAsync(); + + var templateByName = candidates.FirstOrDefault(t => t.Name == templateName); + var templateByScheduleId = candidates.FirstOrDefault(t => t.ScheduleEsppId == esppScheduleId); + + if (templateByName == null && templateByScheduleId == null) + { + // Нет ни по имени, ни по ID + logger.LogWarning( + "Расписание из ЕСПП не привязано ни к одному шаблону: TemplateName='{TemplateName}', ScheduleEsppId='{EsppId}'", + templateName, + esppScheduleId + ); + } + else if (templateByName == null && templateByScheduleId != null) + { + // Есть только по ID → имя не совпадает + logger.LogWarning( + "Расхождение привязки: расписание из ЕСПП с ScheduleEsppId='{EsppId}' и TemplateName='{TemplateName}' " + + "соответствует шаблону в БД с именем '{DbTemplateName}', Id='{TemplateId}'.", + esppScheduleId, + templateName, + templateByScheduleId.Name, + templateByScheduleId.Id + ); + } + else if (templateByName != null) + { + var dbScheduleId = templateByName.ScheduleEsppId ?? string.Empty; + + if (string.IsNullOrEmpty(dbScheduleId)) + { + // Утерян ID в БД + logger.LogWarning( + "У шаблона '{TemplateName}' (Id='{TemplateId}') отсутствует ScheduleEsppId в БД, но в ЕСПП он равен '{EsppId}'", + templateName, + templateByName.Id, + esppScheduleId + ); + } + else if (dbScheduleId != esppScheduleId) + { + // ID не совпадают — проверяем, не занят ли esppScheduleId другим шаблоном + var conflictingTemplate = candidates.FirstOrDefault(t => + t.Id != templateByName.Id && t.ScheduleEsppId == esppScheduleId); + + if (conflictingTemplate != null) + { + logger.LogWarning( + "Конфликт ScheduleEsppId: расписание '{EsppId}' из ЕСПП с именем '{TemplateName}' " + + "уже привязано к другому шаблону '{OtherTemplateName}' (Id='{OtherTemplateId}') в БД.", + esppScheduleId, + templateName, + conflictingTemplate.Name, + conflictingTemplate.Id + ); + } + else + { + logger.LogWarning( + "Несовпадение ScheduleEsppId для шаблона '{TemplateName}' (Id='{TemplateId}'): в БД='{DbId}', в ЕСПП='{EsppId}'", + templateName, + templateByName.Id, + dbScheduleId, + esppScheduleId + ); + } + } + } + + // Передаём оригинальную строку в стандартный синхронизатор await syncService.SyncEsppObjectAsync(str, ParseStrToEsppObject, ConvertDbObjToEsppObj); }