Skip to content

Commit

Permalink
feat: add ReportDeadlineNotificationFunction
Browse files Browse the repository at this point in the history
  • Loading branch information
eduardo committed Sep 4, 2023
1 parent 5b1348e commit b9401ba
Show file tree
Hide file tree
Showing 25 changed files with 1,358 additions and 18 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
namespace Application.Interfaces.UseCases.Notice
{
public interface IReportDeadlineNotification
{
/// <summary>
/// Envia notificação para os professores de que está próximo o prazo de entrega dos relatórios.
/// </summary>
/// <returns>Resultado do processo de notificação</returns>
Task<string> ExecuteAsync();
}
}
61 changes: 61 additions & 0 deletions src/Application/UseCases/Notice/ReportDeadlineNotification.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
using Application.Interfaces.UseCases.Notice;
using Domain.Interfaces.Repositories;
using Domain.Interfaces.Services;

namespace Application.UseCases.Notice
{
public class ReportDeadlineNotification : IReportDeadlineNotification
{
#region Global Scope
private readonly IProjectRepository _projectRepository;
private readonly IEmailService _emailService;
public ReportDeadlineNotification(
IProjectRepository projectRepository,
IEmailService emailService)
{
_projectRepository = projectRepository;
_emailService = emailService;
}
#endregion

public async Task<string> ExecuteAsync()
{
// Verifica se o há projetos que estejam no status Iniciado
var projects = await _projectRepository.GetProjectsWithCloseReportDueDateAsync();
if (!projects.Any())
return "Nenhum projeto com prazo de entrega de relatório próxima.";

// Define datas de comparação
DateTime nextMonth = DateTime.UtcNow.AddMonths(1).Date;
DateTime nextWeek = DateTime.UtcNow.AddDays(7).Date;

// Envia notificação para cada projeto
foreach (var project in projects)
{
// Verifica qual o relatório com data de entrega mais próxima
DateTime reportDeadline = project.Notice!.PartialReportDeadline!.Value.Date;
string reportType;
if (reportDeadline == nextWeek || reportDeadline == nextMonth)
{
reportType = "Relatório Parcial";
}
else
{
reportType = "Relatório Final";
reportDeadline = project.Notice!.FinalReportDeadline!.Value.Date;
}

// Envia notificação para o professor
await _emailService.SendNotificationOfReportDeadlineEmailAsync(
project.Professor!.User!.Email,
project.Professor.User.Name,
project.Title,
reportType,
reportDeadline
);
}

return "Notificação de prazo de entrega de relatório enviada com sucesso.";
}
}
}
1 change: 0 additions & 1 deletion src/Application/UseCases/Project/GenerateCertificate.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
using Domain.Entities.Enums;
using Domain.Interfaces.Repositories;
using Domain.Interfaces.Services;
using Microsoft.AspNetCore.Http;

namespace Application.UseCases.Project
{
Expand Down
9 changes: 9 additions & 0 deletions src/Domain/Interfaces/Repositories/IProjectRepository.cs
Original file line number Diff line number Diff line change
Expand Up @@ -76,5 +76,14 @@ public interface IProjectRepository
/// <param name="noticeId">Id do Edital.</param>
/// <returns>Projetos encontrados.</returns>
Task<IEnumerable<Project>> GetProjectByNoticeAsync(Guid? noticeId);

/// <summary>
/// Obtém projetos que possuem data de entrega de relatório parcial ou final próxima.
/// </summary>
/// <returns>Projetos encontrados.</returns>
/// <remarks>
/// A data de entrega de relatório parcial ou final é considerada próxima quando a mesma está a um mês ou 7 dias de distância.
/// </remarks>
Task<IEnumerable<Project>> GetProjectsWithCloseReportDueDateAsync();
}
}
1 change: 1 addition & 0 deletions src/Domain/Interfaces/Services/IEmailService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,6 @@ public interface IEmailService
Task SendNoticeEmailAsync(string? email, string? name, DateTime? registrationStartDate, DateTime? registrationEndDate, string? noticeUrl);
Task SendProjectNotificationEmailAsync(string? email, string? name, string? projectTitle, string? status, string? description);
Task SendRequestStudentRegisterEmailAsync(string? email);
Task SendNotificationOfReportDeadlineEmailAsync(string? email, string? name, string? projectTitle, string? reportType, DateTime? reportDeadline);
}
}
1 change: 1 addition & 0 deletions src/Infrastructure/IoC/ApplicationDI.cs
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ public static IServiceCollection AddApplication(this IServiceCollection services
services.AddScoped<IGetNoticeById, GetNoticeById>();
services.AddScoped<IGetNotices, GetNotices>();
services.AddScoped<IUpdateNotice, UpdateNotice>();
services.AddScoped<IReportDeadlineNotification, ReportDeadlineNotification>();
#endregion Notice

#region Professor
Expand Down
24 changes: 24 additions & 0 deletions src/Infrastructure/Persistence/Repositories/ProjectRepository.cs
Original file line number Diff line number Diff line change
Expand Up @@ -192,5 +192,29 @@ public async Task<IEnumerable<Project>> GetProjectsToEvaluateAsync(int skip, int
.Take(take)
.ToListAsync();
}

public async Task<IEnumerable<Project>> GetProjectsWithCloseReportDueDateAsync()
{
DateTime nextMonth = DateTime.UtcNow.AddMonths(1);
DateTime nextWeek = DateTime.UtcNow.AddDays(7);
return await _context.Projects
.Include(x => x.Professor)
.Include(x => x.Notice)
.AsAsyncEnumerable()
.Where(x =>
// Contabiliza apenas projetos que estejam no status Iniciado
x.Status is EProjectStatus.Started
&& (
// Data de entrega do relatório parcial deverá ocorrer dentro de 1 mês
(x.Notice!.PartialReportDeadline.HasValue && x.Notice.PartialReportDeadline.Value.Date == nextMonth.Date) ||
// Data de entrega do relatório final deverá ocorrer dentro de 1 mês
(x.Notice!.FinalReportDeadline.HasValue && x.Notice.FinalReportDeadline.Value.Date == nextMonth.Date) ||
// Data de entrega do relatório parcial deverá ocorrer dentro de 7 dias
(x.Notice!.PartialReportDeadline.HasValue && x.Notice.PartialReportDeadline.Value.Date == nextWeek.Date) ||
// Data de entrega do relatório final deverá ocorrer dentro de 7 dias
(x.Notice!.FinalReportDeadline.HasValue && x.Notice.FinalReportDeadline.Value.Date == nextWeek.Date)
))
.ToListAsync();
}
}
}
48 changes: 45 additions & 3 deletions src/Infrastructure/Services/Email/EmailService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,17 @@ public class EmailService : IEmailService
private readonly string? _smtpPassword;
private readonly string? _currentDirectory;
private readonly string? _siteUrl;
private readonly string? _logoGpic;

public EmailService(string? smtpServer, int smtpPort, string? smtpUsername, string? smtpPassword, IConfiguration configuration)
{
_smtpServer = smtpServer;
_smtpPort = smtpPort;
_smtpUsername = smtpUsername;
_smtpPassword = smtpPassword;
_currentDirectory = Path.GetDirectoryName(typeof(EmailService).Assembly.Location);
_currentDirectory = AppContext.BaseDirectory;
_siteUrl = configuration.GetSection("SiteUrl").Value;
_logoGpic = Convert.ToBase64String(File.ReadAllBytes(Path.Combine(_currentDirectory, "Email/Templates/Imgs/logo-gpic-original.svg")));
}
#endregion Global Scope

Expand All @@ -41,7 +43,10 @@ public async Task SendConfirmationEmailAsync(string? email, string? name, string

// Gera mensagem de envio
const string subject = "Confirmação de Cadastro";
string body = template.Replace("#USER_NAME#", name).Replace("#USER_TOKEN#", token);
string body = template
.Replace("#LOGO_GPIC#", _logoGpic)
.Replace("#USER_NAME#", name)
.Replace("#USER_TOKEN#", token);

// Tentativa de envio de email
await SendEmailAsync(email, subject, body);
Expand All @@ -67,7 +72,10 @@ public async Task SendResetPasswordEmailAsync(string? email, string? name, strin

// Gera mensagem de envio
const string subject = "Recuperação de Senha";
string body = template.Replace("#USER_NAME#", name).Replace("#USER_TOKEN#", token);
string body = template
.Replace("#LOGO_GPIC#", _logoGpic)
.Replace("#USER_NAME#", name)
.Replace("#USER_TOKEN#", token);

// Tentativa de envio de email
await SendEmailAsync(email, subject, body);
Expand All @@ -92,6 +100,7 @@ public async Task SendNoticeEmailAsync(string? email, string? name, DateTime? re
// Gera mensagem de envio
const string subject = "Novo Edital";
string body = template
.Replace("#LOGO_GPIC#", _logoGpic)
.Replace("#PROFESSOR_NAME#", name)
.Replace("#START_DATE#", registrationStartDate.Value.ToString("dd/MM/yyyy"))
.Replace("#END_DATE#", registrationEndDate.Value.ToString("dd/MM/yyyy"))
Expand All @@ -117,6 +126,7 @@ public async Task SendProjectNotificationEmailAsync(string? email, string? name,
// Gera mensagem de envio
const string subject = "Alteração de Status de Projeto";
string body = template
.Replace("#LOGO_GPIC#", _logoGpic)
.Replace("#PROFESSOR_NAME#", name)
.Replace("#PROJECT_TITLE#", projectTitle)
.Replace("#PROJECT_STATUS#", status)
Expand Down Expand Up @@ -147,6 +157,7 @@ public async Task SendRequestStudentRegisterEmailAsync(string? email)
// Gera mensagem de envio
const string subject = "Solicitação de Registro";
string body = template
.Replace("#LOGO_GPIC#", _logoGpic)
.Replace("#REGISTRATION_LINK#", _siteUrl);

// Tentativa de envio de email
Expand All @@ -158,6 +169,37 @@ public async Task SendRequestStudentRegisterEmailAsync(string? email)
}
}

public async Task SendNotificationOfReportDeadlineEmailAsync(string? email, string? name, string? projectTitle, string? reportType, DateTime? reportDeadline)
{
try
{
// Verifica se os parâmetros são nulos ou vazios
if (string.IsNullOrEmpty(email) || string.IsNullOrEmpty(name) || string.IsNullOrEmpty(projectTitle) || string.IsNullOrEmpty(reportType) || !reportDeadline.HasValue)
{
throw new Exception("Parâmetros inválidos. Email, nome, título do projeto, tipo de relatório e prazo de entrega são obrigatórios.");
}

// Lê mensagem do template em html salvo localmente
string template = await File.ReadAllTextAsync(Path.Combine(_currentDirectory!, "Email/Templates/NotifyOfReportDeadline.html"));

// Gera mensagem de envio
const string subject = "Entrega de Relatório Próxima";
string body = template
.Replace("#LOGO_GPIC#", _logoGpic)
.Replace("#PROFESSOR_NAME#", name)
.Replace("#PROJECT_TITLE#", projectTitle)
.Replace("#REPORT_TYPE#", reportType)
.Replace("#REPORT_DEADLINE#", reportDeadline.Value.ToString("dd/MM/yyyy"));

// Tentativa de envio de email
await SendEmailAsync(email, subject, body);
}
catch (Exception ex)
{
throw new Exception($"Não foi possível enviar o email de notificação de prazo de entrega de relatório. {ex.Message}");
}
}

#region Private Methods
public async Task SendEmailAsync(string email, string subject, string message)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,10 @@ <h1>Confirmação de Cadastro</h1>
<p class="token">
<span>#USER_TOKEN#</span>
</p>
<p>Atenciosamente, <br /><strong>G-PIC</strong></p>

<div>Atenciosamente,</div>
<img src="data:image/svg+xml;base64,#LOGO_GPIC#" width="200px" />

<p class="signature">
Este e-mail foi enviado automaticamente. Por favor, não responda.
<span class="details">
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading

0 comments on commit b9401ba

Please sign in to comment.