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;
|
2026-08-21 19:27:59 +00:00
|
|
|
|
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
|
|
|
|
}
|
|
|
|
|
|
}
|