From ae2145ac715d80b7c7df4ec6c7ba4b416d92280a Mon Sep 17 00:00:00 2001 From: Eduardo Lopes <155753879+eduardolopesx03@users.noreply.github.com> Date: Tue, 27 Jan 2026 16:55:54 -0300 Subject: [PATCH 1/3] Fix controle recebidos import parsing --- Controllers/LinesController.cs | 61 ++++++++++++++++++++++++---------- 1 file changed, 43 insertions(+), 18 deletions(-) diff --git a/Controllers/LinesController.cs b/Controllers/LinesController.cs index f75f317..486f8da 100644 --- a/Controllers/LinesController.cs +++ b/Controllers/LinesController.cs @@ -1398,10 +1398,19 @@ namespace line_gestao_api.Controllers { await _db.ControleRecebidoLines.ExecuteDeleteAsync(); + var years = new[] { 2022, 2023, 2024, 2025 }; + var importedYears = new HashSet(); + foreach (var info in GetControleRecebidosWorksheets(wb)) + { await ImportControleRecebidosSheet(info.Sheet, info.Year); + importedYears.Add(info.Year); + } + foreach (var year in years) { + if (importedYears.Contains(year)) continue; + var ws = FindControleRecebidosWorksheet(wb, year); if (ws == null) continue; @@ -1476,29 +1485,14 @@ namespace line_gestao_api.Controllers ConteudoDaNf = string.IsNullOrWhiteSpace(conteudo) ? null : conteudo.Trim(), NumeroDaLinha = numeroLinha, ValorUnit = valorUnit, - private sealed class ControleRecebidosWorksheetInfo - { - public ControleRecebidosWorksheetInfo(IXLWorksheet sheet, int year) - { - Sheet = sheet; - Year = year; - } - - public IXLWorksheet Sheet { get; } - public int Year { get; } - } - - private static IEnumerable GetControleRecebidosWorksheets(XLWorkbook wb) - yield return new ControleRecebidosWorksheetInfo(ws, year); + ValorDaNf = valorDaNf, + DataDaNf = dataDaNf, DataDoRecebimento = dataReceb, Quantidade = qtd, IsResumo = isResumo, CreatedAt = now, UpdatedAt = now - var isControleRecebidos = name.Contains("CONTROLE") && name.Contains("RECEBIDOS"); - var isRomaneio = name.Contains("ROMANEIO"); - - if (!isControleRecebidos && !isRomaneio) + }; buffer.Add(e); @@ -1520,6 +1514,37 @@ namespace line_gestao_api.Controllers } } + private sealed class ControleRecebidosWorksheetInfo + { + public ControleRecebidosWorksheetInfo(IXLWorksheet sheet, int year) + { + Sheet = sheet; + Year = year; + } + + public IXLWorksheet Sheet { get; } + public int Year { get; } + } + + private static IEnumerable GetControleRecebidosWorksheets(XLWorkbook wb) + { + var years = new[] { 2022, 2023, 2024, 2025 }; + + foreach (var ws in wb.Worksheets) + { + var name = NormalizeHeader(ws.Name); + var isControleRecebidos = name.Contains("CONTROLE") && name.Contains("RECEBIDOS"); + var isRomaneio = name.Contains("ROMANEIO"); + + if (!isControleRecebidos && !isRomaneio) continue; + + var year = years.FirstOrDefault(y => name.Contains(y.ToString())); + if (year == 0) continue; + + yield return new ControleRecebidosWorksheetInfo(ws, year); + } + } + private static IXLWorksheet? FindControleRecebidosWorksheet(XLWorkbook wb, int year) { var normalizedName = NormalizeHeader($"CONTROLE DE RECEBIDOS {year}"); From e73f181b336994dad30cf99ab1a353e1e9d224d4 Mon Sep 17 00:00:00 2001 From: Eduardo Lopes <155753879+eduardolopesx03@users.noreply.github.com> Date: Tue, 27 Jan 2026 17:13:24 -0300 Subject: [PATCH 2/3] Preserve vigencia notifications on reimport --- Controllers/LinesController.cs | 9 ------- .../VigenciaNotificationBackgroundService.cs | 27 +++++++++++++------ 2 files changed, 19 insertions(+), 17 deletions(-) diff --git a/Controllers/LinesController.cs b/Controllers/LinesController.cs index 486f8da..f4926fb 100644 --- a/Controllers/LinesController.cs +++ b/Controllers/LinesController.cs @@ -1176,15 +1176,6 @@ namespace line_gestao_api.Controllers var startRow = headerRow.RowNumber() + 1; var lastRow = ws.LastRowUsed()?.RowNumber() ?? startRow; - var tenantId = GetTenantIdFromClaims(); - var notificationsQuery = _db.Notifications - .IgnoreQueryFilters() - .Where(n => n.VigenciaLineId != null); - if (tenantId.HasValue) - { - notificationsQuery = notificationsQuery.Where(n => n.TenantId == tenantId.Value); - } - await notificationsQuery.ExecuteDeleteAsync(); await _db.VigenciaLines.ExecuteDeleteAsync(); var buffer = new List(600); diff --git a/Services/VigenciaNotificationBackgroundService.cs b/Services/VigenciaNotificationBackgroundService.cs index 9b22f1d..d97ff91 100644 --- a/Services/VigenciaNotificationBackgroundService.cs +++ b/Services/VigenciaNotificationBackgroundService.cs @@ -190,13 +190,26 @@ public class VigenciaNotificationBackgroundService : BackgroundService return; } - var dedupKeys = candidates.Select(c => c.DedupKey).Distinct().ToList(); - var existingKeys = await db.Notifications.AsNoTracking() - .Where(n => dedupKeys.Contains(n.DedupKey)) - .Select(n => n.DedupKey) + var candidateTipos = candidates.Select(c => c.Tipo).Distinct().ToList(); + var candidateDates = candidates + .Where(c => c.ReferenciaData.HasValue) + .Select(c => c.ReferenciaData!.Value.Date) + .Distinct() + .ToList(); + var existingNotifications = await db.Notifications.AsNoTracking() + .Where(n => n.TenantId == tenantId) + .Where(n => candidateTipos.Contains(n.Tipo)) + .Where(n => n.ReferenciaData != null && candidateDates.Contains(n.ReferenciaData.Value.Date)) .ToListAsync(stoppingToken); - var existingSet = new HashSet(existingKeys); + var existingSet = new HashSet(existingNotifications.Select(n => + BuildDedupKey( + n.Tipo, + n.ReferenciaData!.Value, + n.DiasParaVencer ?? 0, + n.Usuario, + n.Cliente, + n.Linha))); var toInsert = candidates .Where(c => !existingSet.Contains(c.DedupKey)) .ToList(); @@ -232,7 +245,7 @@ public class VigenciaNotificationBackgroundService : BackgroundService ReferenciaData = referenciaData, DiasParaVencer = diasParaVencer, Lida = false, - DedupKey = BuildDedupKey(tipo, vigenciaLineId, referenciaData, diasParaVencer, usuario, cliente, linha), + DedupKey = BuildDedupKey(tipo, referenciaData, diasParaVencer, usuario, cliente, linha), UserId = userId, Usuario = usuario, Cliente = cliente, @@ -244,7 +257,6 @@ public class VigenciaNotificationBackgroundService : BackgroundService private static string BuildDedupKey( string tipo, - Guid vigenciaLineId, DateTime referenciaData, int diasParaVencer, string? usuario, @@ -254,7 +266,6 @@ public class VigenciaNotificationBackgroundService : BackgroundService var parts = new[] { tipo.Trim().ToLowerInvariant(), - vigenciaLineId.ToString(), referenciaData.ToString("yyyy-MM-dd", CultureInfo.InvariantCulture), diasParaVencer.ToString(CultureInfo.InvariantCulture), (usuario ?? string.Empty).Trim().ToLowerInvariant(), From 27ebbbab8536b4d03c64417d8eade0867d9b914c Mon Sep 17 00:00:00 2001 From: Eduardo Lopes <155753879+eduardolopesx03@users.noreply.github.com> Date: Tue, 27 Jan 2026 17:17:57 -0300 Subject: [PATCH 3/3] Fix tenant-scoped vigencia delete --- Controllers/LinesController.cs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/Controllers/LinesController.cs b/Controllers/LinesController.cs index f4926fb..cdfa4ea 100644 --- a/Controllers/LinesController.cs +++ b/Controllers/LinesController.cs @@ -1176,7 +1176,13 @@ namespace line_gestao_api.Controllers var startRow = headerRow.RowNumber() + 1; var lastRow = ws.LastRowUsed()?.RowNumber() ?? startRow; - await _db.VigenciaLines.ExecuteDeleteAsync(); + var tenantId = GetTenantIdFromClaims(); + var vigenciaQuery = _db.VigenciaLines.IgnoreQueryFilters(); + if (tenantId.HasValue) + { + vigenciaQuery = vigenciaQuery.Where(v => v.TenantId == tenantId.Value); + } + await vigenciaQuery.ExecuteDeleteAsync(); var buffer = new List(600);