230 lines
7.2 KiB
C#
230 lines
7.2 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,
|
|
[FromBody] NotificationSelectionRequest? request)
|
|
{
|
|
var utcNow = DateTime.UtcNow;
|
|
var query = ApplySelectionAndFilter(_db.Notifications, filter, request?.NotificationIds)
|
|
.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 = ApplySelectionAndFilter(_db.Notifications.AsNoTracking(), filter, null);
|
|
return await ExportNotificationsAsync(query, filter);
|
|
}
|
|
|
|
[HttpPost("export")]
|
|
[HttpPost("/notifications/export")]
|
|
public async Task<IActionResult> ExportNotifications(
|
|
[FromQuery] string? filter,
|
|
[FromBody] NotificationSelectionRequest? request)
|
|
{
|
|
var query = ApplySelectionAndFilter(_db.Notifications.AsNoTracking(), filter, request?.NotificationIds);
|
|
return await ExportNotificationsAsync(query, filter);
|
|
}
|
|
|
|
private async Task<IActionResult> ExportNotificationsAsync(IQueryable<Notification> query, string? 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(
|
|
notification.Linha ?? vigencia.Linha,
|
|
notification.Cliente ?? vigencia.Cliente,
|
|
notification.Usuario ?? vigencia.Usuario,
|
|
notification.ReferenciaData ?? vigencia.DtTerminoFidelizacao,
|
|
notification.Tipo))
|
|
.ToListAsync();
|
|
|
|
using var workbook = new XLWorkbook();
|
|
var worksheet = workbook.Worksheets.Add("Notificacoes");
|
|
|
|
var normalizedFilter = NormalizeFilter(filter);
|
|
var dateHeader = normalizedFilter switch
|
|
{
|
|
"vencidas" or "vencido" => "Data da Expiração",
|
|
"a-vencer" or "avencer" => "Data a Vencer",
|
|
_ => "Data de Referência"
|
|
};
|
|
|
|
var headers = new[]
|
|
{
|
|
"Número da Linha",
|
|
"Cliente",
|
|
"Usuário",
|
|
dateHeader,
|
|
"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.Linha ?? string.Empty;
|
|
worksheet.Cell(rowIndex, 2).Value = row.Cliente ?? string.Empty;
|
|
worksheet.Cell(rowIndex, 3).Value = row.Usuario ?? string.Empty;
|
|
worksheet.Cell(rowIndex, 4).Value = row.DataReferencia;
|
|
worksheet.Cell(rowIndex, 5).Value = row.Tipo;
|
|
}
|
|
|
|
worksheet.Column(1).Width = 18;
|
|
worksheet.Column(2).Width = 26;
|
|
worksheet.Column(3).Width = 24;
|
|
worksheet.Column(4).Width = 20;
|
|
worksheet.Column(5).Width = 14;
|
|
|
|
worksheet.Column(4).Style.DateFormat.Format = "dd/MM/yyyy";
|
|
|
|
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> ApplySelectionAndFilter(
|
|
IQueryable<Notification> query,
|
|
string? filter,
|
|
IReadOnlyCollection<Guid>? notificationIds)
|
|
{
|
|
query = ApplyFilter(query, filter);
|
|
|
|
if (notificationIds is { Count: > 0 })
|
|
{
|
|
query = query.Where(n => notificationIds.Contains(n.Id));
|
|
}
|
|
|
|
return query;
|
|
}
|
|
|
|
private static IQueryable<Notification> ApplyFilter(IQueryable<Notification> query, string? filter)
|
|
{
|
|
var normalized = NormalizeFilter(filter);
|
|
return normalized switch
|
|
{
|
|
"a-vencer" or "avencer" => query.Where(n => n.Tipo == "AVencer"),
|
|
"vencidas" or "vencido" => query.Where(n => n.Tipo == "Vencido"),
|
|
_ => query
|
|
};
|
|
}
|
|
|
|
private static string? NormalizeFilter(string? filter)
|
|
{
|
|
return filter?.Trim().ToLowerInvariant();
|
|
}
|
|
|
|
private sealed record NotificationExportRow(
|
|
string? Linha,
|
|
string? Cliente,
|
|
string? Usuario,
|
|
DateTime? DataReferencia,
|
|
string Tipo);
|
|
|
|
public sealed class NotificationSelectionRequest
|
|
{
|
|
public List<Guid>? NotificationIds { get; set; }
|
|
}
|
|
|
|
}
|