using System.Globalization; using System.Text; using MailKit.Net.Smtp; using Marco.Pms.Model.Utilities; using Marco.Pms.Model.ViewModels.Report; using Microsoft.Extensions.Options; using MimeKit; namespace MarcoBMS.Services.Service { public class EmailSender : IEmailSender { private readonly SmtpSettings _smtpSettings; private readonly IConfiguration _configuration; private readonly IWebHostEnvironment _env; public EmailSender(IOptions emailSettings, IConfiguration configuration, IWebHostEnvironment env) { _smtpSettings = emailSettings.Value; _configuration = configuration; _env = env; } public async Task GetEmailTemplate(string templateName, Dictionary replacements) { string path = Path.Combine(_env.ContentRootPath, "EmailTemplates", $"{templateName}.html"); if (!File.Exists(path)) throw new FileNotFoundException("Template file not found"); string content = await File.ReadAllTextAsync(path); foreach (var item in replacements) { content = content.Replace($"{{{{{item.Key}}}}}", item.Value); } return content; } //public async Task GetEmailTemplate1() //{ // string path = Path.Combine(_env.ContentRootPath, "EmailTemplates", $"send-otp.html"); // if (!File.Exists(path)) // throw new FileNotFoundException("Template file not found"); // string content = await File.ReadAllTextAsync(path); // return content; //} public async Task SendResetPasswordEmailOnRegister(string toEmail, string toName, string resetLink) { var replacements = new Dictionary { { "MAIL_TITLE", "New registration,Reset Your Password" }, { "RESET_PWD_URL", resetLink }, { "RECEIVER_NAME", toName } }; List toEmails = new List { toEmail }; string emailBody = await GetEmailTemplate("new-user-email", replacements); await SendEmailAsync(toEmails, "New user registration, Reset Your Password", emailBody); } public async Task SendResetPasswordEmail(string toEmail, string userName, string resetLink) { var replacements = new Dictionary { { "MAIL_TITLE", "Reset Your Password" }, { "RESET_PWD_URL", resetLink } }; string emailBody = await GetEmailTemplate("forgot-password", replacements); List toEmails = new List { toEmail }; await SendEmailAsync(toEmails, "Reset Your Password", emailBody); } public async Task SendResetPasswordSuccessEmail(string toEmail, string toName) { var replacements = new Dictionary { { "MAIL_TITLE", "Reset Password Successful" }, { "RECEIVER_NAME", toName } }; string emailBody = await GetEmailTemplate("password-change-success", replacements); List toEmails = new List { toEmail }; await SendEmailAsync(toEmails, "Password Changed Successfully", emailBody); } public async Task SendRequestDemoEmail(List toEmails, InquiryEmailObject demoEmailObject) { var replacements = new Dictionary { { "MAIL_TITLE", "User Requested a Demo" }, { "ORGANIZATION_NAME", demoEmailObject.OrganizatioinName ?? string.Empty }, { "EMAIL", demoEmailObject.Email ?? string.Empty}, { "ABOUT", demoEmailObject.About ?? string.Empty }, { "ORGANIZATION_SIZE", demoEmailObject.OragnizationSize ?? string.Empty }, { "INDUSTRY_NAME", demoEmailObject.IndustryName ?? string.Empty }, { "CONTACT_NAME", demoEmailObject.ContactPerson ?? string.Empty }, { "CONTACT_NUMBER", demoEmailObject.ContactNumber ?? string.Empty } }; string emailBody = await GetEmailTemplate("request-demo", replacements); await SendEmailAsync(toEmails, "User Requested a Demo", emailBody); } public async Task SendProjectStatisticsEmail(List toEmails, string emailBody, string subject, ProjectStatisticReport report) { var date = report.Date.ToString("dd-MMM-yyyy", CultureInfo.InvariantCulture); var replacements = new Dictionary { {"DATE", date}, {"PROJECT_NAME", report.ProjectName}, {"TIMESTAMP", report.TimeStamp}, {"TODAYS_ATTENDANCES", report.TodaysAttendances.ToString("N0")}, {"TOTAL_EMPLOYEES", report.TotalEmployees.ToString("N0")}, {"TODAYS_PLANNED", report.TotalPlannedTask.ToString("N0")}, {"TODAYS_COMPLETED", report.TotalCompletedTask.ToString("N0")}, {"REGULARIZATION_PENDING", report.RegularizationPending.ToString("N0")}, {"CHECKOUT_PENDING", report.CheckoutPending.ToString("N0")}, {"TOTAL_PLANNED", report.TotalPlannedWork.ToString("N0")}, {"TOTAL_COMPLETED", report.TotalCompletedWork.ToString("N0")}, {"PROJECT_STATUS", report.CompletionStatus.ToString("P")}, {"TODAYS_ASSIGNED", report.TodaysAssignTasks.ToString("N0")}, {"REPORT_PENDING", report.ReportPending.ToString("N0")} }; foreach (var item in replacements) { emailBody = emailBody.Replace($"{{{{{item.Key}}}}}", item.Value); } emailBody = emailBody.Replace("{{TEAM_ON_SITE}}", BuildTeamOnSiteHtml(report.TeamOnSite)); emailBody = emailBody.Replace("{{PERFORMED_TASK}}", BuildPerformedTaskHtml(report.PerformedTasks, report.Date)); emailBody = emailBody.Replace("{{PERFORMED_ATTENDANCE}}", BuildPerformedAttendanceHtml(report.PerformedAttendance)); if (!string.IsNullOrWhiteSpace(subject)) { var subjectReplacements = new Dictionary { {"DATE", date }, {"PROJECT_NAME", report.ProjectName} }; foreach (var item in subjectReplacements) { subject = subject.Replace($"{{{{{item.Key}}}}}", item.Value); } string env = _configuration["environment:Title"] ?? string.Empty; subject = CheckSubject(subject); } if (toEmails.Count > 0) { await SendEmailAsync(toEmails, subject, emailBody); } return emailBody; } public async Task SendOTP(List toEmails, string emailBody, string name, string otp, string subject) { var replacements = new Dictionary { { "NAME", name }, { "OTP", otp } }; foreach (var item in replacements) { emailBody = emailBody.Replace($"{{{{{item.Key}}}}}", item.Value); } subject = CheckSubject(subject); await SendEmailAsync(toEmails, subject, emailBody); } public async Task SendEmailAsync(List toEmails, string subject, string body) { var email = new MimeMessage(); email.From.Add(new MailboxAddress(_smtpSettings.SenderName, _smtpSettings.SenderEmail)); foreach (var toEmail in toEmails) { email.To.Add(MailboxAddress.Parse(toEmail)); } email.Subject = subject; var bodyBuilder = new BodyBuilder { HtmlBody = body }; email.Body = bodyBuilder.ToMessageBody(); using var smtp = new SmtpClient(); await smtp.ConnectAsync(_smtpSettings.SmtpServer, _smtpSettings.Port, MailKit.Security.SecureSocketOptions.StartTls); await smtp.AuthenticateAsync(_smtpSettings.SenderEmail, _smtpSettings.Password); await smtp.SendAsync(email); await smtp.DisconnectAsync(true); } private string CheckSubject(string subject) { string env = _configuration["Environment:Title"] ?? string.Empty; if (string.IsNullOrWhiteSpace(env)) { return subject = $"{subject}"; } else { return subject = $"({env}) {subject}"; } } private string BuildTeamOnSiteHtml(List team) { if (team == null || !team.Any()) return ""; var sb = new StringBuilder(); sb.Append(""); int count = 0; foreach (var member in team) { if (count == 6) { sb.Append(""); count = 0; } sb.AppendFormat( "" + "
" + "
{0}
" + "
{1}
" + "
", member.RoleName, member.NumberofEmployees); count++; } sb.Append(""); return sb.ToString(); } private string BuildPerformedTaskHtml(List tasks, DateTime reportDate) { if (tasks == null || !tasks.Any()) { return "" + "" + "No Activities (Tasks) Performed Today"; } var sb = new StringBuilder(); foreach (var task in tasks) { sb.AppendFormat("" + "{0}
" + "{1}" + "{2} / {3}" + "{4}" + "{5}" + "", task.Activity, task.Location, task.AssignedToday, task.Pending, task.CompletedToday, reportDate.ToString("dd-MMM-yyyy")); foreach (var member in task.Team) { sb.AppendFormat("{0} ({1})
", member.Name, member.RoleName); } sb.AppendFormat("{0}", task.Comment); } return sb.ToString(); } private string BuildPerformedAttendanceHtml(List attendances) { if (attendances == null || !attendances.Any()) { return "" + "No Attendance Performed Today"; } var sb = new StringBuilder(); foreach (var a in attendances) { sb.AppendFormat("" + "{0}" + "{1}" + "{2}" + "{3}" + "{4}" + "", a.Name, a.RoleName, a.InTime.ToString("dd-MMM-yyyy h:mm tt", CultureInfo.InvariantCulture), a.OutTime?.ToString("dd-MMM-yyyy h:mm tt", CultureInfo.InvariantCulture) ?? "", a.Comment); } return sb.ToString(); } } }