sozsoft-platform/api/modules/Sozsoft.MailQueue/Domain/MailQueueWorker.cs

121 lines
4.7 KiB
C#
Raw Normal View History

2026-10-17 18:51:10 +00:00
using Sozsoft.MailQueue.Domain.Entities;
2026-02-24 20:44:16 +00:00
using Sozsoft.MailQueue.Domain.MailGeneration;
using Sozsoft.MailQueue.Domain.Shared;
using Sozsoft.Sender.Mail;
2026-02-24 20:44:16 +00:00
using Volo.Abp.BackgroundWorkers;
using Volo.Abp.Domain.Repositories;
using Volo.Abp.Timing;
using Volo.Abp.Uow;
namespace Sozsoft.MailQueue.Domain;
public class MailQueueWorker : BackgroundWorkerBase
{
public Guid TemplateId { get; set; }
public string TemplateName { get; set; }
public MailQueueWorkerOptions Options { get; set; }
protected ISozsoftEmailSender ErpEmailSender { get; }
2026-10-17 18:51:10 +00:00
protected IRepository<BackgroundWorker_MailQueue> Repository { get; }
2026-02-24 20:44:16 +00:00
public IClock Clock { get; }
public ILogManager LogManager { get; }
public ITableGenerator TableGenerator { get; }
public IMailBodyGenerator MailBodyGenerator { get; }
public IAttachmentGenerator AttachmentGenerator { get; }
public MailQueueWorker(
2026-04-27 21:29:03 +00:00
ISozsoftEmailSender erpEmailSender,
2026-10-17 18:51:10 +00:00
IRepository<BackgroundWorker_MailQueue> repository,
2026-02-24 20:44:16 +00:00
IClock clock,
ILogManager logManager,
ITableGenerator tableGenerator,
IMailBodyGenerator mailBodyGenerator,
2026-10-17 18:51:10 +00:00
IAttachmentGenerator attachmentGenerator)
2026-02-24 20:44:16 +00:00
{
2026-04-27 21:29:03 +00:00
ErpEmailSender = erpEmailSender;
2026-02-24 20:44:16 +00:00
Repository = repository;
Clock = clock;
LogManager = logManager;
TableGenerator = tableGenerator;
MailBodyGenerator = mailBodyGenerator;
AttachmentGenerator = attachmentGenerator;
}
/// <summary>
2026-10-17 18:51:10 +00:00
/// Şablonun (TemplateId) gönderilmemiş kuyruk kayıtlarını işler: her kayıt için tablo, gövde ve
/// ekler üretilir, mail gönderilir, sonuç kayda yazılır. Akış: tablo → gövde → ekler → gönderim.
2026-02-24 20:44:16 +00:00
/// </summary>
public override async Task StartAsync(CancellationToken cancellationToken = default)
{
var uowManager = LazyServiceProvider.LazyGetRequiredService<IUnitOfWorkManager>();
using var uow = uowManager.Begin();
var jobId = $"{TemplateId}-{Clock.Now:yyyy-MM-dd-HH-mm-ss}";
var queues = await Repository.GetListAsync(a => a.TemplateId == TemplateId && !a.SendStatus, cancellationToken: cancellationToken);
foreach (var queue in queues)
{
2026-10-17 18:51:10 +00:00
// Her kayıt kendi UoW'sinde: bir kaydın hatası diğerlerinin gönderimini ve kaydını düşürmez.
2026-02-24 20:44:16 +00:00
using var uow2 = uowManager.Begin(requiresNew: true, isTransactional: false);
try
{
2026-10-17 18:51:10 +00:00
await ProcessQueueAsync(queue, jobId, cancellationToken);
await uow2.CompleteAsync(cancellationToken);
2026-02-24 20:44:16 +00:00
}
catch (Exception ex)
{
LogManager.LogError($"Hata. Kuyruk Id: {queue.Id}. {ex}", "HATA", "KUYRUK", queue.Id, jobId);
}
}
2026-10-17 18:51:10 +00:00
await uow.CompleteAsync(cancellationToken);
}
private async Task ProcessQueueAsync(BackgroundWorker_MailQueue queue, string jobId, CancellationToken cancellationToken)
{
var tables = await TableGenerator.GenerateAsync(queue.TableName, queue.TableParameter, queue.Id);
var mailBody = await MailBodyGenerator.GenerateAsync(
TemplateName,
queue.MailParameter,
queue.Id,
tables,
jobId);
// Ekler tablo şablonlarından (IN olmayanlar: PDF, XLS, TXT) üretilir.
var attachments = await AttachmentGenerator.GenerateAsync(tables.Values.ToList(), queue.Id, jobId);
// IN olmayan bir tablo belirtilmiş ama hiçbiri üretilememişse hata vardır, gönderilmez.
if (tables.Values.Any(a => a.DosyaTipi != "IN") && attachments.IsNullOrEmpty())
{
2026-10-19 14:35:08 +00:00
LogManager.LogWarning("Table attachments could not be generated", "ATTACHMENT", "KUYRUK", queue.Id, jobId);
2026-10-17 18:51:10 +00:00
return;
}
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)
{
queue.AwsMessageId = result.MessageId;
}
else
{
2026-10-19 14:35:08 +00:00
LogManager.LogWarning($"Mail could not be sent. Message: {result.ErrorMessage}", "MAILSEND", "KUYRUK", queue.Id, jobId);
2026-10-17 18:51:10 +00:00
queue.AwsMessageId = result.ErrorMessage;
}
2026-02-24 20:44:16 +00:00
2026-10-17 18:51:10 +00:00
queue.SendStatus = result.Success;
queue.SendTime = Clock.Now;
await Repository.UpdateAsync(queue, cancellationToken: cancellationToken);
2026-02-24 20:44:16 +00:00
}
}