line-gestao-api/Controllers/NotificationsController.cs

208 lines
6.9 KiB
C#

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<ActionResult<List<NotificationDto>>> 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<IActionResult> 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<IActionResult> 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<IActionResult> 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<Notification> ApplyFilter(IQueryable<Notification> 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);
}