using ClosedXML.Excel; using line_gestao_api.Data; using line_gestao_api.Dtos; using line_gestao_api.Models; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore; namespace line_gestao_api.Controllers; [ApiController] [Route("api/notifications")] [Authorize] public class NotificationsController : ControllerBase { private readonly AppDbContext _db; public NotificationsController(AppDbContext db) { _db = db; } [HttpGet] [HttpGet("/notifications")] public async Task>> GetNotifications() { var query = _db.Notifications.AsNoTracking(); var items = await query .OrderByDescending(n => n.Data) .Select(n => new NotificationDto { Id = n.Id, Tipo = n.Tipo, Titulo = n.Titulo, Mensagem = n.Mensagem, Data = n.Data, ReferenciaData = n.ReferenciaData, DiasParaVencer = n.DiasParaVencer, Lida = n.Lida, LidaEm = n.LidaEm, VigenciaLineId = n.VigenciaLineId, Cliente = n.Cliente, Linha = n.Linha }) .ToListAsync(); return Ok(items); } [HttpPatch("{id:guid}/read")] [HttpPatch("/notifications/{id:guid}/read")] public async Task MarkAsRead(Guid id) { var notification = await _db.Notifications .FirstOrDefaultAsync(n => n.Id == id); if (notification is null) { return NotFound(); } if (!notification.Lida) { notification.Lida = true; notification.LidaEm = DateTime.UtcNow; await _db.SaveChangesAsync(); } return NoContent(); } [HttpPatch("read-all")] [HttpPatch("/notifications/read-all")] public async Task MarkAllAsRead([FromQuery] string? filter) { var utcNow = DateTime.UtcNow; var query = ApplyFilter(_db.Notifications, filter) .Where(n => !n.Lida); await query.ExecuteUpdateAsync(updates => updates .SetProperty(n => n.Lida, true) .SetProperty(n => n.LidaEm, utcNow)); return NoContent(); } [HttpGet("export")] [HttpGet("/notifications/export")] public async Task ExportNotifications([FromQuery] string? filter) { var query = ApplyFilter(_db.Notifications.AsNoTracking(), filter); var rows = await ( from notification in query join vigencia in _db.VigenciaLines.AsNoTracking() on notification.VigenciaLineId equals vigencia.Id into vigencias from vigencia in vigencias.DefaultIfEmpty() orderby notification.ReferenciaData descending, notification.Data descending select new NotificationExportRow( vigencia == null ? null : vigencia.Item, vigencia == null ? null : vigencia.Conta, vigencia == null ? null : vigencia.Linha, vigencia == null ? null : vigencia.Cliente, vigencia == null ? null : vigencia.Usuario, vigencia == null ? null : vigencia.PlanoContrato, vigencia == null ? null : vigencia.DtEfetivacaoServico, vigencia == null ? null : vigencia.DtTerminoFidelizacao, vigencia == null ? null : vigencia.Total, notification.Tipo)) .ToListAsync(); using var workbook = new XLWorkbook(); var worksheet = workbook.Worksheets.Add("Notificacoes"); var headers = new[] { "Item (ID)", "Conta", "Linha", "Cliente", "Usuário", "Plano Contrato", "DT. DE EFETIVAÇÃO DO SERVIÇO", "DT. DE TÉRMINO DA FIDELIZAÇÃO", "TOTAL", "Status" }; for (var i = 0; i < headers.Length; i++) { worksheet.Cell(1, i + 1).Value = headers[i]; } var headerRange = worksheet.Range(1, 1, 1, headers.Length); headerRange.Style.Font.Bold = true; headerRange.Style.Fill.BackgroundColor = XLColor.LightGray; headerRange.Style.Alignment.Horizontal = XLAlignmentHorizontalValues.Center; for (var i = 0; i < rows.Count; i++) { var row = rows[i]; var rowIndex = i + 2; worksheet.Cell(rowIndex, 1).Value = row.Item; worksheet.Cell(rowIndex, 2).Value = row.Conta ?? string.Empty; worksheet.Cell(rowIndex, 3).Value = row.Linha ?? string.Empty; worksheet.Cell(rowIndex, 4).Value = row.Cliente ?? string.Empty; worksheet.Cell(rowIndex, 5).Value = row.Usuario ?? string.Empty; worksheet.Cell(rowIndex, 6).Value = row.PlanoContrato ?? string.Empty; worksheet.Cell(rowIndex, 7).Value = row.DtEfetivacaoServico; worksheet.Cell(rowIndex, 8).Value = row.DtTerminoFidelizacao; worksheet.Cell(rowIndex, 9).Value = row.Total; worksheet.Cell(rowIndex, 10).Value = row.Tipo; } worksheet.Column(1).Width = 12; worksheet.Column(2).Width = 18; worksheet.Column(3).Width = 18; worksheet.Column(4).Width = 22; worksheet.Column(5).Width = 22; worksheet.Column(6).Width = 20; worksheet.Column(7).Width = 22; worksheet.Column(8).Width = 24; worksheet.Column(9).Width = 14; worksheet.Column(10).Width = 14; worksheet.Column(7).Style.DateFormat.Format = "dd/MM/yyyy"; worksheet.Column(8).Style.DateFormat.Format = "dd/MM/yyyy"; worksheet.Column(9).Style.NumberFormat.Format = "#,##0.00"; worksheet.Columns().AdjustToContents(); using var stream = new MemoryStream(); workbook.SaveAs(stream); stream.Position = 0; var fileName = $"notificacoes-{DateTime.UtcNow:yyyyMMddHHmmss}.xlsx"; return File( stream.ToArray(), "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", fileName); } private static IQueryable ApplyFilter(IQueryable query, string? filter) { var normalized = filter?.Trim().ToLowerInvariant(); return normalized switch { "a-vencer" or "avencer" => query.Where(n => n.Tipo == "AVencer"), "vencidas" or "vencido" => query.Where(n => n.Tipo == "Vencido"), _ => query }; } private sealed record NotificationExportRow( int? Item, string? Conta, string? Linha, string? Cliente, string? Usuario, string? PlanoContrato, DateTime? DtEfetivacaoServico, DateTime? DtTerminoFidelizacao, decimal? Total, string Tipo); }