using Kurs.Sender.Mail; using Kurs.MailQueue.Domain.MailGeneration; using Kurs.MailQueue.Domain.Shared; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Volo.Abp.BackgroundWorkers; using Volo.Abp.Domain.Repositories; using Volo.Abp.Guids; using Volo.Abp.Timing; using Volo.Abp.Uow; namespace Kurs.MailQueue.Domain; public class MailQueueWorker : BackgroundWorkerBase { public Guid TemplateId { get; set; } public string TemplateName { get; set; } public MailQueueWorkerOptions Options { get; set; } protected IKursEmailSender KursEmailSender { get; } protected IRepository Repository { get; } public IClock Clock { get; } public IConfiguration Configuration { get; } public ILogManager LogManager { get; } public ITableGenerator TableGenerator { get; } public IMailBodyGenerator MailBodyGenerator { get; } public IAttachmentGenerator AttachmentGenerator { get; } public IGuidGenerator GuidGenerator { get; } public MailQueueWorker( IKursEmailSender kursEmailSender, IRepository repository, IClock clock, IConfiguration configuration, ILogManager logManager, ITableGenerator tableGenerator, IMailBodyGenerator mailBodyGenerator, IAttachmentGenerator attachmentGenerator, IGuidGenerator guidGenerator ) { KursEmailSender = kursEmailSender; Repository = repository; Clock = clock; Configuration = configuration; LogManager = logManager; TableGenerator = tableGenerator; MailBodyGenerator = mailBodyGenerator; AttachmentGenerator = attachmentGenerator; GuidGenerator = guidGenerator; } /// /// ID'si verilen Template satırının kuyruk kayıtlarını proses ederek bildirimleri yapar /// public override async Task StartAsync(CancellationToken cancellationToken = default) { /* * TemplateId'den ilgili template satırını al * TemplateId'den ilgili kuyruk kayıtlarını al * Bu kurallar inclusive'dir. * Yani birden fazla kural aynı kuyruk kaydı için işletilebilir. * BeforeSP varsa çalıştır. * SP görevini yaptıktan sonra devam et * Template: * Dosya Tipi: NULL, PDF, XLS, IN * NULL: Sadece mail body * PDF, XLS, TXT, XML, HTML, RTF: Bu durumda ilgili rapor hazırlanıp eklenir * IN: Tablo, mail body'e gömülür * Tablo: * Mail Body metni oluşturulacak * Kuyruk tablosu MAILPARAMETRE alanı ile * MAILTEMPLATE'de belirtilen HTML üretilerek * mail body oluşturulur * Tablo Alanı dolu ise; * Belirtilen tablodan kayıtları al ve Kuyruk'taki * TABLOPARAMETRE ve TABLO alanlarına göre tabloyu oluştur * ve Dosya Tipi'ne göre bildirime ekle. * Bu durumda ilgili Tabloda belirtilen css ve başlıklar kullanılmalı * Kuyruk - ATTACHMENT ve ATTACHMENTPARAMETRE dolu ise; * Bu alanlarda belirtilen raporlar Access API ile * oluşturulup DOSYA TIPI'ne göre bildirime eklenecek * Gönderimi Yap * KUYRUK - GATEWAYTEMPLATEID alanında belirtilen template ile * mail gateway'de ilgili template gönderimi yapılır * KIMDEN ve KIME alanları kullanılır. * Gateway'e gönderim emri verildikten sonra * GonderilmeTarihi alanı setlenir. * AFTERSP'de belirtilen SP'yi veritabanında çalıştır * */ /* Options: - Mail gidecek kişiler listesi - Mail subject - Mail lojik türü - Kayıt kaynağı - RS Filtre (id, vs) - 1- Template Id'ye göre, Kuyruk tablosunu filtrele 2- Her kayıt için mail gönder */ using var scope = ServiceProvider.CreateScope(); var uowManager = LazyServiceProvider.LazyGetRequiredService(); using var uow = uowManager.Begin(); var jobId = $"{TemplateId}-{Clock.Now:yyyy-MM-dd-HH-mm-ss}"; var attachmentsBasePath = Configuration.GetValue("App:AttachmentsPath"); //var template = await RepositoryTemplate.GetAsync(a => a.Id == templateId); var queues = await Repository.GetListAsync(a => a.TemplateId == TemplateId && !a.SendStatus, cancellationToken: cancellationToken); foreach (var queue in queues) { using var uow2 = uowManager.Begin(requiresNew: true, isTransactional: false); try { //LogManager.LogInformation("Kuyruk process başladı", "KUYRUK", "KUYRUK", kuyruk.Id, jobId); // Tablo oluştur var tables = await TableGenerator.GenerateAsync(queue.TableName, queue.TableParameter, queue.Id); //LogManager.LogInformation($"{tables.Count} adet tablo oluşturuldu", "TABLO", "KUYRUK", kuyruk.Id, jobId); // Mail Body oluştur var mailBody = await MailBodyGenerator.GenerateAsync( TemplateName, queue.MailParameter, queue.Id, tables, jobId); //LogManager.LogInformation($"Mail Body oluşturuldu", "MAILBODY", "KUYRUK", kuyruk.Id, jobId); // Attachment oluştur // Iki attachment türü var: // 1- ATTACHMENT alanı dolu olanlar var attachments = await AttachmentGenerator.GenerateAsync(queue.Id, queue.Attachment, queue.AttachmentParameter, jobId); if (!queue.Attachment.IsNullOrWhiteSpace() && attachments.IsNullOrEmpty()) { //Kuyruk uzerinde Attachment var fakat hicbiri olusturulamis, devam etmeyelim LogManager.LogWarning("Attachmentlar oluşturulamadı", "ATTACHMENT", "KUYRUK", queue.Id, jobId); continue; } //LogManager.LogInformation($"{attachments.Count} adet attachment oluşturuldu", "ATTACHMENT", "KUYRUK", kuyruk.Id, jobId); // 2- Tablo (IN olmayanlar-PDF,XLS,TXT) var attachmentsTable = await AttachmentGenerator.GenerateAsync(tables.Values.ToList(), queue.Id, jobId); // IN olmayan herhangi bir tablo belirtilmisse fakat bu tablo attachment olarak uretilememisse, hata vardir if (tables.Values.Where(a => a.DosyaTipi != "IN").Any() && attachmentsTable.IsNullOrEmpty()) { //NULL ise hata olmustur, devam etmeyelim LogManager.LogWarning("Tablo Attachmentlar oluşturulamadı", "ATTACHMENT", "KUYRUK", queue.Id, jobId); continue; } //LogManager.LogInformation($"{attachmentsTable.Count} adet attachment-tablo oluşturuldu", "ATTACHMENT-TABLO", "KUYRUK", kuyruk.Id, jobId); foreach (var attachmentTable in attachmentsTable) { var key = attachmentTable.Key; if (attachments.ContainsKey(key)) { key += "-" + GuidGenerator.Create(); } attachments.Add(key, attachmentTable.Value); } //LogManager.LogInformation($"Mail hazırlandı. Gönderim yapılıyor", "MAILSEND", "KUYRUK", kuyruk.Id, jobId); // Gönderimi yap var senderKeyValue = queue.From.Split(":"); var sender = new KeyValuePair( senderKeyValue.ElementAtOrDefault(0), senderKeyValue.ElementAtOrDefault(1)); var result = await KursEmailSender.SendEmailAsync( queue.To.Split(";").Select(a => a.Trim()).ToArray(), sender, null, mailBody, Options.MailSubject, attachments, true); if (result.Success) { //LogManager.LogInformation($"Mail gönderildi. {result.MessageId}", "MAILSEND", "KUYRUK", kuyruk.Id, jobId); queue.AwsMessageId = result.MessageId; } else { LogManager.LogWarning($"Mail gönderilemedi. Gelen Mesaj: {result.ErrorMessage}", "MAILSEND", "KUYRUK", queue.Id, jobId); queue.AwsMessageId = result.ErrorMessage; } queue.SendStatus = result.Success; queue.SendTime = Clock.Now; await Repository.UpdateAsync(queue); // Attachmentlari silebiliriz try { var attachmentsPath = Path.Combine(attachmentsBasePath, $"{queue.Id}-{jobId}"); if (Directory.Exists(attachmentsPath)) { Directory.Delete(attachmentsPath, true); } } catch (Exception ex) { LogManager.LogError($"Attachments klasörü silinemedi. Kuyruk Id: {queue.Id}. {ex}", "HATA", "ATTACHMENT", queue.Id, jobId); } } catch (Exception ex) { LogManager.LogError($"Hata. Kuyruk Id: {queue.Id}. {ex}", "HATA", "KUYRUK", queue.Id, jobId); } await uow2.SaveChangesAsync(cancellationToken); } await uow.SaveChangesAsync(cancellationToken); //LogManager.LogInformation($"Template process bitti. {kuyruklar.Count} adet kuyruk kaydı işlendi", "TEMPLATE", "TEMPLATE", templateId, jobId); //Logger.LogInformation("Executed MailWorker..!"); } }