using FabApprovalWorkerService.Models; using FabApprovalWorkerService.Services; using Infineon.Monitoring.MonA; using Quartz; using System.Net.Mail; using System.Text; namespace FabApprovalWorkerService.Workers; public class TrainingNotificationWorker : IJob { private readonly ILogger _logger; private readonly ITrainingService _trainingService; private readonly IUserService _userService; private readonly IECNService _ecnService; private readonly ISmtpService _smtpService; private readonly IMonInClient _monInClient; private readonly string _baseUrl; public TrainingNotificationWorker(ILogger logger, ITrainingService trainingService, IUserService userService, IECNService ecnService, ISmtpService smtpService, IMonInClient monInClient) { _logger = logger ?? throw new ArgumentNullException("ILogger not injected"); _trainingService = trainingService ?? throw new ArgumentNullException("ITrainingService not injected"); _userService = userService ?? throw new ArgumentNullException("IUserService not injected"); _ecnService = ecnService ?? throw new ArgumentNullException("IECNService not injected"); _smtpService = smtpService ?? throw new ArgumentNullException("ISmtpService not injected"); _monInClient = monInClient ?? throw new ArgumentNullException("IMonInClient not injected"); _baseUrl = Environment.GetEnvironmentVariable("FabApprovalBaseUrl") ?? throw new ArgumentNullException("FabApprovalBaseUrl environment variable not found"); } public async Task Execute(IJobExecutionContext context) { DateTime start = DateTime.Now; bool isInternalError = false; StringBuilder errorMessage = new(); string metricName = "TrainingNotificationWorker"; try { _logger.LogInformation("Attempting to send training notifications"); IEnumerable trainingAssignments = await _trainingService.GetActiveTrainingAssignments(); _logger.LogInformation($"There are {trainingAssignments.Count()} active training assignments"); foreach (TrainingAssignment trainingAssignment in trainingAssignments) { int ecnNumber = await _trainingService.GetEcnNumberByTrainingId(trainingAssignment.TrainingID); ECN ecn = await _ecnService.GetEcnByNumber(ecnNumber); bool ecnIsExpired = _ecnService.EcnIsExpired(ecn); if (ecnIsExpired) { _logger.LogInformation($"ECN {ecn.ECNNumber} is expired. Cancelling all training."); await _trainingService.DeleteTrainingAssignmentsByTrainingId(trainingAssignment.TrainingID); await _trainingService.DeleteDocAssignment(trainingAssignment.ID); await _trainingService.MarkTrainingAsComplete(trainingAssignment.TrainingID); } User user = await _userService.GetUserById(trainingAssignment.UserID); bool userIsActive = user.IsActive; if (!userIsActive) { _logger.LogInformation($"User {user.UserID} is inactive. Cancelling all training."); IEnumerable userTrainingAssignmentIds = await _trainingService.GetTrainingAssignmentIdsByUserId(user.UserID); foreach (int trainingAssignmentId in userTrainingAssignmentIds) { await _trainingService.DeleteTrainingAssignmentById(trainingAssignmentId); await _trainingService.DeleteDocAssignment(trainingAssignmentId); } } if (!ecnIsExpired && userIsActive && !user.OOO) { bool lastNotificationMoreThanFourDaysAgo = (DateTime.Now.Date - trainingAssignment.LastNotification).Days >= 5; bool dateAssignedMoreThanFourDaysAgo = (DateTime.Now.Date - trainingAssignment.DateAssigned).Days >= 5; bool notificationSent = false; if (lastNotificationMoreThanFourDaysAgo && dateAssignedMoreThanFourDaysAgo) { await SendTrainingReminder(ecn, user); notificationSent = true; await _trainingService.UpdateTrainingAssignmentLastNotification(trainingAssignment.ID); } if (!notificationSent) { DateTime latestExpirationDate = (ecn.ExtensionDate > ecn.ExpirationDate ? ecn.ExtensionDate : ecn.ExpirationDate); int daysTillExpiration = (latestExpirationDate - DateTime.Now.Date).Days; if (daysTillExpiration > 0 && daysTillExpiration <= 5) { await SendTrainingReminder(ecn, user); await _trainingService.UpdateTrainingAssignmentLastNotification(trainingAssignment.ID); } } } } _logger.LogInformation("Successfully sent training notifications"); } catch (Exception ex) { StringBuilder errMsgBuilder = new(); errMsgBuilder.Append("An exception occurred when attempting to send training notifications. "); errMsgBuilder.Append($"Exception: {ex.Message}"); _logger.LogError(errMsgBuilder.ToString()); isInternalError = true; } finally { DateTime end = DateTime.Now; double latencyInMS = (end - start).TotalMilliseconds; _monInClient.PostMetric(metricName + "Latency", latencyInMS); if (isInternalError) { _monInClient.PostStatus(metricName, State.Critical); } else { _monInClient.PostStatus(metricName, State.Ok); } } } private async Task SendTrainingReminder(ECN ecn, User user) { _logger.LogInformation($"Attempting to send training reminder for ECN {ecn.ECNNumber} to user {user.UserID}"); IEnumerable recipients = new List() { new MailAddress(user.Email) }; IEnumerable ccRecipients = new List(); StringBuilder bodyBuilder = new(); bodyBuilder.Append("Hello, you have open training assignments in Fab Approval. This is a reminder to "); bodyBuilder.Append("finish your training assignments.
View your open training assignments "); bodyBuilder.Append($"here. "); string subject = $"Fab Approval Training Reminder - ECN# {ecn.ECNNumber} - {ecn.Title}"; await _smtpService.SendEmail(recipients, ccRecipients, subject, bodyBuilder.ToString()); } }