using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using Oms.Application.Messaging.OrderSideEffects; using Oms.Application.Messaging.ParcelCreate; using Oms.Application.Services.Orders.Batch; using Oms.Domain.OrdersAggregate.Repositories; namespace Oms.Application.Integrations.SmallBagTrack; internal sealed class SmallBagTrackOrderNotifier( IServiceScopeFactory scopeFactory, ILogger logger) : ISmallBagTrackOrderNotifier { public void Enqueue(SmallBagTrackUpsertRequest request, int orderId, int? customerId = null) { _ = Task.Run(async () => { try { using var scope = scopeFactory.CreateScope(); var orderRepository = scope.ServiceProvider.GetRequiredService(); var order = await orderRepository.FirstOrDefaultAsync(x => x.Id == orderId); if (order == null) { return; } var publisher = scope.ServiceProvider.GetRequiredService(); await publisher.PublishTrackUpsertAsync(order, request, customerId); } catch (Exception ex) { logger.LogWarning( ex, "Track upsert publish failed, fallback via batch coordinator. orderId={OrderId}", orderId); await FallbackBatchOrDirectAsync(request, orderId, customerId); } }); } private async Task FallbackBatchOrDirectAsync( SmallBagTrackUpsertRequest request, int orderId, int? customerId) { try { using var scope = scopeFactory.CreateScope(); var coordinator = scope.ServiceProvider.GetRequiredService(); var published = await coordinator.PublishTrackUpsertAsync(request, orderId, customerId); if (!published) { var client = scope.ServiceProvider.GetRequiredService(); await client.UpsertAsync(request); } } catch (Exception ex) { logger.LogWarning(ex, "Direct UpsertSmallBag failed for orderId={OrderId} orderNo={OrderNo}", orderId, request.OrderNo); } } public void EnqueueLifecycleTrackAppend(string orderNo, string trackCode, int orderId, string? authorization = null) { _ = PublishLifecycleAsync(orderNo, trackCode, orderId, authorization); } private async Task PublishLifecycleAsync( string orderNo, string trackCode, int orderId, string? authorization) { try { using var scope = scopeFactory.CreateScope(); var publisher = scope.ServiceProvider.GetRequiredService(); await publisher.PublishLifecycleTrackAppendAsync(orderId, orderNo, trackCode, authorization); } catch (Exception ex) { logger.LogWarning( ex, "Lifecycle track append publish failed. orderId={OrderId} orderNo={OrderNo} trackCode={TrackCode}", orderId, orderNo, trackCode); } } }