using Microsoft.EntityFrameworkCore; namespace Drab.Logic.Services; public class OrderProcessor : IOrderProcessor { private readonly ILogger _logger; private readonly IServiceScopeFactory _serviceScopeFactory; private readonly IPrintService _printService; private readonly IOrderPdfGenerator _orderPdfGenerator; private readonly OrderEventBus _eventBus; public OrderProcessor(IServiceScopeFactory serviceScopeFactory, IPrintService printService, IOrderPdfGenerator orderPdfGenerator, OrderEventBus eventBus, ILogger logger) { _serviceScopeFactory = serviceScopeFactory; _printService = printService; _orderPdfGenerator = orderPdfGenerator; _eventBus = eventBus; _logger = logger; } public async Task ProcessOrder(DokDto order) { var dok = await GetOrCreateOrder(order); if (dok.IsPrinted) return; var filePath = await EnsureOrderPdfExists(order, dok); var printResult = await PrintOrder(order, filePath); if (printResult.IsSuccess) { dok.IsPrinted = true; await SaveOrderIfChanged(dok); } } private async Task GetOrCreateOrder(DokDto order) { var dok = await GetOrder(order.DokId); if (dok != null) return dok; _logger.LogInformation("Creating new order - {OrderNo}", order.NrDok); dok = new OrderDb { DokId = order.DokId, Created = order.Data, OrderId = order.DokId, Filename = string.Empty, IsPrinted = false, Shop = order.Sklep, OrderNumber = order.NrDok }; await SaveOrderIfChanged(dok); return dok; } private async Task EnsureOrderPdfExists(DokDto order, OrderDb dok) { if (!string.IsNullOrEmpty(dok.Filename)) { var fullPath = Path.Combine(Constants.ReportsOutputPath, dok.Filename); if (File.Exists(fullPath)) return fullPath; } _logger.LogInformation("Generating order file: {OrderNo}", order.NrDok); var generatedFilename = await _orderPdfGenerator.GenerateOrder(order); var newPath = Path.Combine(Constants.ReportsOutputPath, generatedFilename); if (string.Equals(dok.Filename, generatedFilename, StringComparison.OrdinalIgnoreCase)) return newPath; dok.Filename = generatedFilename; await SaveOrderIfChanged(dok); return newPath; } private async Task PrintOrder(DokDto order, string filePath) { _logger.LogInformation("Printing order: {OrderNo}", order.NrDok); var result = await _printService.PrintPdf(new PrintDocumentRequest(filePath, order.DokId)); _logger.LogInformation("Printing result - OrderNo: {OrderNo}, Success: {IsSuccess}, Message: {Message}", order.NrDok, result.IsSuccess, result.Message); return result; } private async Task GetOrder(long dokId) { try { using var scope = _serviceScopeFactory.CreateScope(); var context = scope.ServiceProvider.GetRequiredService(); return await context.Orders .FirstOrDefaultAsync(x => x.DokId == dokId); } catch (Exception e) { _logger.LogError(e, "Error retrieving order from database"); return null; } } private async Task SaveOrderIfChanged(OrderDb order) { using var scope = _serviceScopeFactory.CreateScope(); var context = scope.ServiceProvider.GetRequiredService(); var existing = await context.Orders.FirstOrDefaultAsync(x => x.DokId == order.DokId); if (existing == null) { await context.Orders.AddAsync(order); await context.SaveChangesAsync(); _eventBus.NotifyOrdersChanged(); return; } if (existing.IsPrinted == order.IsPrinted && existing.Filename == order.Filename) return; existing.IsPrinted = order.IsPrinted; existing.Filename = order.Filename; context.Orders.Update(existing); await context.SaveChangesAsync(); _eventBus.NotifyOrdersChanged(); } }