erp-platform/api/modules/Erp.MailQueue/Domain/MailQueueWorker.cs
2025-11-11 22:49:52 +03:00

227 lines
9.9 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using Erp.Sender.Mail;
using Erp.MailQueue.Domain.MailGeneration;
using Erp.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 Erp.MailQueue.Domain;
public class MailQueueWorker : BackgroundWorkerBase
{
public Guid TemplateId { get; set; }
public string TemplateName { get; set; }
public MailQueueWorkerOptions Options { get; set; }
protected IErpEmailSender ErpEmailSender { get; }
protected IRepository<Entities.BackgroundWorker_MailQueue> 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(
IErpEmailSender ErpEmailSender,
IRepository<Entities.BackgroundWorker_MailQueue> repository,
IClock clock,
IConfiguration configuration,
ILogManager logManager,
ITableGenerator tableGenerator,
IMailBodyGenerator mailBodyGenerator,
IAttachmentGenerator attachmentGenerator,
IGuidGenerator guidGenerator
)
{
ErpEmailSender = ErpEmailSender;
Repository = repository;
Clock = clock;
Configuration = configuration;
LogManager = logManager;
TableGenerator = tableGenerator;
MailBodyGenerator = mailBodyGenerator;
AttachmentGenerator = attachmentGenerator;
GuidGenerator = guidGenerator;
}
/// <summary>
/// ID'si verilen Template satırının kuyruk kayıtlarını proses ederek bildirimleri yapar
/// </summary>
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<IUnitOfWorkManager>();
using var uow = uowManager.Begin();
var jobId = $"{TemplateId}-{Clock.Now:yyyy-MM-dd-HH-mm-ss}";
var attachmentsBasePath = Configuration.GetValue<string>("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<string, string>(
senderKeyValue.ElementAtOrDefault(0),
senderKeyValue.ElementAtOrDefault(1));
var result = await ErpEmailSender.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..!");
}
}