Fix notification export data and selection support

This commit is contained in:
Eduardo Lopes 2026-02-02 09:28:53 -03:00
parent a3f308c877
commit b5c410b9cf
1 changed files with 78 additions and 56 deletions

View File

@ -72,10 +72,12 @@ public class NotificationsController : ControllerBase
[HttpPatch("read-all")] [HttpPatch("read-all")]
[HttpPatch("/notifications/read-all")] [HttpPatch("/notifications/read-all")]
public async Task<IActionResult> MarkAllAsRead([FromQuery] string? filter) public async Task<IActionResult> MarkAllAsRead(
[FromQuery] string? filter,
[FromBody] NotificationSelectionRequest? request)
{ {
var utcNow = DateTime.UtcNow; var utcNow = DateTime.UtcNow;
var query = ApplyFilter(_db.Notifications, filter) var query = ApplySelectionAndFilter(_db.Notifications, filter, request?.NotificationIds)
.Where(n => !n.Lida); .Where(n => !n.Lida);
await query.ExecuteUpdateAsync(updates => updates await query.ExecuteUpdateAsync(updates => updates
@ -89,41 +91,53 @@ public class NotificationsController : ControllerBase
[HttpGet("/notifications/export")] [HttpGet("/notifications/export")]
public async Task<IActionResult> ExportNotifications([FromQuery] string? filter) public async Task<IActionResult> ExportNotifications([FromQuery] string? filter)
{ {
var query = ApplyFilter(_db.Notifications.AsNoTracking(), 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 ( var rows = await (
from notification in query from notification in query
join vigencia in _db.VigenciaLines.AsNoTracking() join vigencia in _db.VigenciaLines.AsNoTracking()
on notification.VigenciaLineId equals vigencia.Id into vigencias on notification.VigenciaLineId equals vigencia.Id into vigencias
from vigencia in vigencias.DefaultIfEmpty() from vigencia in vigencias.DefaultIfEmpty()
orderby notification.ReferenciaData descending, notification.Data descending orderby notification.ReferenciaData descending, notification.Data descending
select new NotificationExportRow( select new NotificationExportRow(
vigencia == null ? null : vigencia.Item, notification.Linha ?? vigencia.Linha,
vigencia == null ? null : vigencia.Conta, notification.Cliente ?? vigencia.Cliente,
vigencia == null ? null : vigencia.Linha, notification.Usuario ?? vigencia.Usuario,
vigencia == null ? null : vigencia.Cliente, notification.ReferenciaData ?? vigencia.DtTerminoFidelizacao,
vigencia == null ? null : vigencia.Usuario, notification.Tipo))
vigencia == null ? null : vigencia.PlanoContrato,
vigencia == null ? null : vigencia.DtEfetivacaoServico,
vigencia == null ? null : vigencia.DtTerminoFidelizacao,
vigencia == null ? null : vigencia.Total,
notification.Tipo))
.ToListAsync(); .ToListAsync();
using var workbook = new XLWorkbook(); using var workbook = new XLWorkbook();
var worksheet = workbook.Worksheets.Add("Notificacoes"); 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[] var headers = new[]
{ {
"Item (ID)", "Número da Linha",
"Conta",
"Linha",
"Cliente", "Cliente",
"Usuário", "Usuário",
"Plano Contrato", dateHeader,
"DT. DE EFETIVAÇÃO DO SERVIÇO",
"DT. DE TÉRMINO DA FIDELIZAÇÃO",
"TOTAL",
"Status" "Status"
}; };
@ -141,32 +155,20 @@ public class NotificationsController : ControllerBase
{ {
var row = rows[i]; var row = rows[i];
var rowIndex = i + 2; var rowIndex = i + 2;
worksheet.Cell(rowIndex, 1).Value = row.Item; worksheet.Cell(rowIndex, 1).Value = row.Linha ?? string.Empty;
worksheet.Cell(rowIndex, 2).Value = row.Conta ?? string.Empty; worksheet.Cell(rowIndex, 2).Value = row.Cliente ?? string.Empty;
worksheet.Cell(rowIndex, 3).Value = row.Linha ?? string.Empty; worksheet.Cell(rowIndex, 3).Value = row.Usuario ?? string.Empty;
worksheet.Cell(rowIndex, 4).Value = row.Cliente ?? string.Empty; worksheet.Cell(rowIndex, 4).Value = row.DataReferencia;
worksheet.Cell(rowIndex, 5).Value = row.Usuario ?? string.Empty; worksheet.Cell(rowIndex, 5).Value = row.Tipo;
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(1).Width = 18;
worksheet.Column(2).Width = 18; worksheet.Column(2).Width = 26;
worksheet.Column(3).Width = 18; worksheet.Column(3).Width = 24;
worksheet.Column(4).Width = 22; worksheet.Column(4).Width = 20;
worksheet.Column(5).Width = 22; worksheet.Column(5).Width = 14;
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(4).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(); worksheet.Columns().AdjustToContents();
@ -181,9 +183,24 @@ public class NotificationsController : ControllerBase
fileName); 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) private static IQueryable<Notification> ApplyFilter(IQueryable<Notification> query, string? filter)
{ {
var normalized = filter?.Trim().ToLowerInvariant(); var normalized = NormalizeFilter(filter);
return normalized switch return normalized switch
{ {
"a-vencer" or "avencer" => query.Where(n => n.Tipo == "AVencer"), "a-vencer" or "avencer" => query.Where(n => n.Tipo == "AVencer"),
@ -192,16 +209,21 @@ public class NotificationsController : ControllerBase
}; };
} }
private static string? NormalizeFilter(string? filter)
{
return filter?.Trim().ToLowerInvariant();
}
private sealed record NotificationExportRow( private sealed record NotificationExportRow(
int? Item,
string? Conta,
string? Linha, string? Linha,
string? Cliente, string? Cliente,
string? Usuario, string? Usuario,
string? PlanoContrato, DateTime? DataReferencia,
DateTime? DtEfetivacaoServico,
DateTime? DtTerminoFidelizacao,
decimal? Total,
string Tipo); string Tipo);
public sealed class NotificationSelectionRequest
{
public List<Guid>? NotificationIds { get; set; }
}
} }